Skip to content

Instantly share code, notes, and snippets.

@laprasdrum
Created June 13, 2022 09:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laprasdrum/df3eef5f79ad692aaf6b3fd4445739f2 to your computer and use it in GitHub Desktop.
Save laprasdrum/df3eef5f79ad692aaf6b3fd4445739f2 to your computer and use it in GitHub Desktop.
some and any keywords for generic protocols in Swift 5.7
/*
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