Swift: Concrete types in Protocol
Suppose you are writing a language-translation app. The requirement is quite simple: Given a word, translate it from a language into another language.
Here’s a simple approach. We define a protocol TranslatorType
as follows
class Language {
var words: [Word] = []
}
class VI_Language: Language { }
class EN_Language: Language { }
protocol TranslatorType {
var sourceLanguage: Language { get }
var destLanguage: Language { get }
func translate(word: Word) -> Word
}
The VI_EN_Translator
(which translates Vietnamese into English) should
conform to that protocol with sourceLanguage
as VI_Language
and
destLanguage
as EN_Language
.
class VI_EN_Translator: TranslatorType {
private(set) var sourceLanguage = VI_Language()
private(set) var destLanguage = EN_Language()
func translate(word: Word) -> Word {
...
}
}
It seems reasonable. Unfortunately, I got an error from XCode: “Type
VI_EN_Translator does not conform to protocol TranslatorType” despite the fact
that VI_Language
is a subclass of Language
. I don’t want to change
sourceLanguage to Language and cast it to VI_Language
every I use it.
Not sure wheter we should blame Swift/XCode/Apple for that. Here’s a tip to overcome this issue:
class VI_EN_Translator: TranslatorType {
private var _sourceLanguage = VI_Language()
private var _destLanguage = EN_Language()
var sourceLanguage: Language {
return _sourceLanguage
}
var destLanguage: Language {
return _destLanguage
}
func translate(word: Word) -> Word {
...
}
}
This code still satisfies the protocol requirements and also allows us to use
particular properties/functions of the concrete types via _sourceLanguage
,
_destLanguage
.