這是不明確的,因爲Int
是Hashable
和Comparable
,並且這兩個協議都不在同一個層次結構中。 (您可以查看Int
protocol hierarchy on Swifter)
func f<T: Hashable>(t: T) {
println("Hashable: \(t)")
}
func f<T: Comparable>(t: T) {
println("Comparable: \(t)")
}
let number = 5
f(number)
// error: ambiguous use of 'f'
你不能明確告訴的,因爲每個協議的相關類型要求它調用哪個函數,但你可以做定義是第三個功能:
func f<T: Comparable where T: Hashable>(t: T) {
println("Both Hashable & Comparable: \(t)")
}
f(number)
// Both Hashable & Comparable: 5
這是怎麼Swift implements的..<
操作,否則將是曖昧實現既Comparable
和ForwardIndexType
類型。
爲了進一步擴大一點,這裏就來看看我的意思是「你不能明確告訴它調用哪個函數,因爲每個協議的相關類型的需求。」協議可以被用作類型,如在夫特書chapter on Protocols描述:
protocol RandomNumberGenerator {
func random() -> Double
}
class Dice {
let generator: RandomNumberGenerator
// ...
}
在這個例子中,發生器屬性可以是任何類型的符合RandomNumberGenerator
- 類似id<ProtocolName>
是如何在Objective-C使用。但是,協議可以使用只有作爲類型,但它們的聲明中不包含關聯類型或參考Self
。這不幸地排除了Swift中幾乎所有的內置類型,包括Hashable
和Comparable
。從Equatable
Hashable
繼承,限定==
操作者當其引用Self
:
func ==(lhs: Self, rhs: Self) -> Bool
和Comparable
不與其運行相同:
func <=(lhs: Self, rhs: Self) -> Bool
// similar definitions for <, >, and >=
這些協議可以僅被用作通用約束,並且在聲明變量時不用作類型。 (據我所知,這是無證的,但通過錯誤消息可以發現。)
兩個協議的不這個限制是Printable
和BooleanType
,所以我們可以看看他們是如何工作的。 Bool
是唯一符合BooleanType
的內置類型,它也是Printable
,所以這將是我們的測試類型。這是我們的通用功能p()
和可變t
- 值得注意的是,和以前一樣,我們不能只調用函數與t
:
func p<T: Printable>(t: T) {
println("Printable: \(t)")
}
func p<T: BooleanType>(t: T) {
println("BooleanType: \(t)")
}
let t: Bool = true
p(t)
// error: Ambiguous use of 'p'
相反,我們需要轉換(向上轉型?)t
特定協議使用as
關鍵字,並調用特定的通用功能的方法:所以只要我們有一個合格的協議
p(t as Printable)
// Printable: true
p(t as BooleanType)
// BooleanType: true
,我們可以選擇調用的泛型方法的變型。
'job(myInt as Hashable)'工作嗎? – 2014-09-29 20:36:42
Nope :(我得到2個錯誤: 'Protocol'Hashable'只能用作通用約束,因爲它具有Self或Assosiated類型的要求' AND'Type'Hashable'不符合協議'Comparable''一個聽起來很奇怪:)) – 2014-09-29 20:41:05
FYI爲最新的快速注意這兩個很好的答案... http://stackoverflow.com/a/39836054/294884 ... http://stackoverflow.com/a/39835658/294884 – Fattie 2016-10-18 20:07:01