How to call a static property in the Swift protocol from a common function?

Given this code:

public protocol Selectable { typealias T var selected: Bool { get } static var defaultValue: T { get } } public func selected<T: Selectable>(items: [T]) -> T { if let selected = items.filter({$0.selected}).first { return selected } return T.defaultValue } 

I get an error in the returned string: "It is not possible to convert the returned expression of type" TT "to the expected return type" T ".

Changing it to return T.defaultValue as! T return T.defaultValue as! T seems to work, but it makes no sense to me. Am I missing something or should I send a radar?

+6
source share
2 answers

You can use Self in the protocol:

 public protocol Selectable { var selected: Bool { get } static var defaultValue: Self { get } // ^^^^ } public func selected<T: Selectable>(items: [T]) -> T { if let selected = items.filter({$0.selected}).first { return selected } return T.defaultValue } 

OR, if you want to use typealias , you need to:

 public protocol Selectable { typealias Value var selected: Bool { get } static var defaultValue: Value { get } } public func selected<T: Selectable where T.Value == T>(items: [T]) -> T { // ^^^^^^^^^^^^^^^^^^ if let selected = items.filter({$0.selected}).first { return selected } return T.defaultValue } 
+7
source

Based on @ rintaro's answer, using Self for type defaultValue means typealias not needed:

 public protocol Selectable { var selected: Bool { get } static var defaultValue: Self { get } } public func selected<T: Selectable >(items: [T]) -> T { if let selected = items.filter({$0.selected}).first { return selected } return T.defaultValue } 

(I found this as changing the defaultValue type to Self , and my implementation class no longer matched the protocol, and I noticed that I didn’t even refer to typealias Value ; deleting, which is why my implementation class matched again).

+1
source

Source: https://habr.com/ru/post/984624/


All Articles