Я недавно загрузил xCode 6 и играл с языком Swift. До сих пор мне это нравится. Я читал на Swift-функциях, и один из них, который мне очень нравится, - это вывод. Однако в образце кода, который я создал для создания протоколов в Swift, я получаю проблему, которую я не совсем понимаю, поэтому надеялся, что кто-то поможет выяснить, что происходит. Возможно, я что-то упускаю. Таким образом, в примере кодаБыстрое поведение, вывод и поведение протокола
Я создал протокол Animal
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 не соответствует протоколу„Animal“, а также предупреждение о том,» Переменная выводится так, чтобы иметь тип «AnyObject», который может быть неожиданным. Я думал, что из-за вывода, он должен автоматически реализовать Dog и Cat в соответствии с протоколом Animal. Когда я ранее печатал метод разговора, мне не нужно было указывать тип Animal. Так Тогда я обновил переменную внутри метода петли так явно указано, что объект соответствует типу животных, как так
var an : Animal = ar[i]
Это снимает предупреждение, однако ошибка не будет устранена. Почему это так? Я прямо сказал, что этот объект соответствует протоколу Animal. Я могу сделать это в Objective-c без такой проблемы
for(int i = 0; i < array.count; i++)
{
id <Animal> an = [ar objectAtIndex:i];
[an speak];
}
Так почему же это не работает в Swift?
Затем я обновил оригинальную декларацию animal1 и animal2, так это выглядит, как этот
var animal1 : Animal = Dog()
var animal2 = Cat()
Или я могу сделать это
var animal1 = Dog()
var animal2 : Animal = Cat()
И ушла ошибка. Почему мне нужно только обновить одну из переменных, чтобы они соответствовали протоколу Animal, а не оба?
Был бы благодарен, если кто-нибудь разъяснит, что здесь происходит? Может быть, я просто не хватает что-то
Заранее спасибо
Objective-c также имеет множество протоколов, но не имеет этой проблемы. В качестве теста я быстро создал случайный протокол в Objc-C и добавил его в класс cat, но не для класса собаки. Однако в Obj-c я могу проверить, соответствует ли класс протоколу, можно ли что-то подобное сделать в Swift? – AdamM
Вы можете проверить с помощью 'is'. Например, «если собака - это животное». Еще лучше вы можете сделать бросок, который возвращает необязательное значение, содержащее некоторое значение, если бросок был успешным или нулевым, если он не был успешным. Например, var var = arr [0] as? Dog' – Kirsteins
В obj-c он работает, потому что он не использует generics, поэтому компилятор не пытается принудительно выполнить проверку типа для элементов в массиве. В быстрых случаях они должны быть одного типа или наследовать/реализовывать от общего предка. – Antonio