Created
March 28, 2016 17:57
-
-
Save sunshinejr/2377d44276a4627a8b54 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: #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