我最近下載了xCode 6並一直在玩Swift語言。到目前爲止,我很享受它。我正在閱讀Swift特性,其中一個我很喜歡的是推理。然而,在我創建的用於在Swift中實踐創建協議的代碼示例中,我遇到了一個我不太明白的問題,因此希望有人能幫助澄清發生了什麼。也許我錯過了一些東西。因此,爲了該代碼示例Swift,推理和協議行爲
我創建了一個協議動物
protocol Animal
{
func speak()
}
然後創建一個符合動物協議,例如狗和貓類
class Dog: Animal {
func speak()
{
println("Woof");
}
}
然後創建了狗和貓的變量,以檢查它的工作如預期
var animal1 = Dog()
var animal2 = Cat()
println(animal1.speak())
println(animal2.speak())
沒有問題爲止。於是我決定將這些通過對象添加到一個數組和循環,並打印出來
var ar = [animal1, animal2];
for var i = 0; i < ar.count; i++
{
var an = ar[i]
println(an.speak())
}
但是我得到一個錯誤說「AnyObject不符合協議的‘動物’,以及一個警告說」變量被推斷爲具有可能意外的「AnyObject」類型。我認爲,由於推論,它應該自動實現狗和貓符合動物協議。當我以前打印說法時,我不需要指定動物類型。所以後來我更新了循環方法中的變量,因此明確規定,對象符合動物類型,像這樣
var an : Animal = ar[i]
這消除了警告,但錯誤依然存在。爲什麼會這樣?我明確告訴它,這個對象符合Animal協議。我能做到這一點在Objective-C沒有這樣
for(int i = 0; i < array.count; i++)
{
id <Animal> an = [ar objectAtIndex:i];
[an speak];
}
一個問題,那麼,爲什麼不這項工作斯威夫特?
我再更新animal1和animal2的正本報關,所以它看起來像這樣
var animal1 : Animal = Dog()
var animal2 = Cat()
或者,我可以做到這一點
var animal1 = Dog()
var animal2 : Animal = Cat()
和錯誤消失了。爲什麼我只需要更新其中一個變量來表示符合協議Animal,而不是兩者?
如果有人能夠澄清這裏發生了什麼,請將此表示感謝!也許我只是失去了一些東西提前
Objective-c也有多個協議通過,但是沒有這個問題。作爲測試,我很快在Objc-C中創建了隨機協議,並將其添加到貓類,但不是狗類。然而,在Obj-c中,我可以檢查一個類是否符合協議,在Swift中可以做類似的事情嗎? – AdamM 2014-09-25 10:16:25
你可以用'is'來檢查。例如,「如果狗是動物」。更好的是,如果投射成功,你可以做一個返回包含某個值的可選值的投射,如果投射不成功,則可以爲零。例如,'var dog = arr [0] as? Dog' – Kirsteins 2014-09-25 10:22:07
在obj-c中它可以工作,因爲它不使用泛型,所以編譯器不會嘗試對數組中的元素執行類型檢查。相反,它們必須是相同的類型,或者從共同的祖先繼承/實現。 – Antonio 2014-09-25 10:26:03