Reputation: 24718
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 on the return line: "Cannot convert return expression of type 'T.T' to expected return type 'T'".
Changing it to return T.defaultValue as! T
seems to work but that doesn't make any sense to me. Am I missing something or should I file a radar?
Upvotes: 6
Views: 3586
Reputation: 24718
Building on @rintaro's answer, using Self
for the type of defaultValue
means the typealias
is unnecessary:
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 defaultValue
's type to Self
made my implementing class not conform to the protocol anymore—and I noticed I wasn't even referring to the typealias Value
; removing that made my implementing class comply again.)
Upvotes: 1
Reputation: 51911
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 have 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
}
Upvotes: 7