Skip to content

Instantly share code, notes, and snippets.

@sunshinejr
Created March 28, 2016 17:57
Show Gist options
  • Save sunshinejr/2377d44276a4627a8b54 to your computer and use it in GitHub Desktop.
Save sunshinejr/2377d44276a4627a8b54 to your computer and use it in GitHub Desktop.
//: #typealias & associatedtype magic
//: ##Let's make a protocol without typealias (now associatedtype)
protocol Testable {
}
//: ##And another one with typealias
//: You could think, that the below typealias is just making
//: a typealiast for Int. In fact, we actually created a
//: generic protocol.
protocol TestableGeneric {
typealias Type = Int
}
//: What the above code means is that you create an associated type
//: and assign the default value to it (in our case it is Int). That's why
//: the keyword is changed, it was really misleading. Now you see the warning
//: about typealias being deprecated in protocol (in Swift 2.2), and that's neat.
//: To make sure this is actually a generic protocol, let's make a test.
//: We will make an array of the types we defined above:
let array = [Testable]() // Here we have a success, normal protocol it is.
//let array2 = [TestableGeneric]() // Here we have an error, because TestableGeneric is a generic protocol.
//: ##What about extensions to protocol?
//: Let's say we create typealias to protocol in extension.
extension Testable {
typealias Type = Int
}
let array3 = [Testable]() // This still works, but why?
//: In extensions, typealias is doing its normal thing: being typealias, not associatedtype.
//: That's why you don't see the warning about deprecated typealias keyword. Quite interesting!
//: #Default associatedtype & overriding
//: Let's make an example of how can you use default associatedtype, to make clear what
//: it really does.
//: We will create generic protocol for Container, with associatedtype for ItemType.
//: Our ItemType will haave a default value of Int.
protocol Container {
associatedtype ItemType = Int
func getItem() -> ItemType
func getItems() -> [ItemType]
}
class Backpack: Container { // because ItemType has default associatedtype, we don't have to specify it
func getItem() -> Backpack.ItemType {
return 2
}
func getItems() -> [Backpack.ItemType] {
return [2]
}
}
struct TypedBackpack<TypedItemType: StringLiteralConvertible>: Container { // but we can override current associatedtype quite easily
func getItem() -> TypedItemType { // Because ItemType doesn't need to conform to any protocol, we can easily pass our own ItemType
return ""
}
func getItems() -> [TypedItemType] {
return [""]
}
}
let backpack1 = Backpack()
let backpack2 = TypedBackpack<String>()
print(backpack1.getItem())
print(backpack2.getItem())
//: #Example of using typealias as an alias for a type (instead of associated type) in protocols.
protocol CurrencyProtocol { }
extension CurrencyProtocol {
typealias Currency = Double
}
struct ReallyImportantCurrencyStruct: CurrencyProtocol {
func currencyFunction() -> ReallyImportantCurrencyStruct.Currency {
return 2.0
}
}
let currency = ReallyImportantCurrencyStruct()
print(currency.currencyFunction())
let currencies = [CurrencyProtocol]()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment