Created
June 13, 2022 09:32
-
-
Save laprasdrum/df3eef5f79ad692aaf6b3fd4445739f2 to your computer and use it in GitHub Desktop.
some and any keywords for generic protocols in Swift 5.7
This file contains 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
/* | |
some and any keywords for generic protocols in Swift 5.7 | |
https://swiftbysundell.com/articles/referencing-generic-protocols-with-some-and-any-keywords/ | |
*/ | |
protocol Item { } | |
struct User { | |
let name: String | |
var isAnonymous: Bool { | |
return name.isEmpty | |
} | |
} | |
protocol Group { | |
associatedtype Item | |
var items: [Item] { get } | |
var users: [User] { get } | |
} | |
/* | |
Runtime Error: | |
required by global function 'namesOfUsers(addedTo:)' where 'some Group' = 'any Group' | |
As I use namesOfUsers in showDepartment with `some Collection<any Group>` typed groups, | |
The below error happens at `print(namesOfUsers(addedTo: group))`. | |
error: type 'any Group' cannot conform to 'Group' | |
only concrete types such as structs, enums and classes can conform to protocols | |
*/ | |
//func namesOfUsers(addedTo group: some Group) -> [String] { | |
func namesOfUsers(addedTo group: any Group) -> [String] { | |
group.users.compactMap { user in | |
user.isAnonymous ? nil : user.name | |
} | |
} | |
struct Devs: Group { | |
typealias Item = Int | |
let items: [Int] | |
let users: [User] | |
} | |
let devs = Devs(items: [1,2,3,4,5], | |
users: ["", "bob", "john", "", "kate"].map(User.init)) | |
print(namesOfUsers(addedTo: devs)) | |
// ["bob", "john", "kate"] | |
// Here's another group. | |
struct Designers: Group { | |
typealias Item = String | |
let items: [String] | |
let users: [User] | |
} | |
let designers = Designers(items: ["graphics", "navigation", "architecture", "requirements"], | |
users: ["", "elen", "steve", ""].map(User.init)) | |
func showDepartment(consistsOf groups: some Collection<any Group>) { | |
groups.forEach { group in | |
print(group.items) | |
print(namesOfUsers(addedTo: group)) | |
} | |
} | |
let groups: [any Group] = [devs, designers] | |
showDepartment(consistsOf: groups) | |
/* | |
[1, 2, 3, 4, 5] | |
["bob", "john", "kate"] | |
["graphics", "navigation", "architecture", "requirements"] | |
["elen", "steve"] | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment