Swift 2.0 beta: действительно ли протоколы нарушены в Xcode beta 5?
В настоящее время я работаю над своим новым приложением, написанным на Swift 2.0. Сегодня я столкнулся с двумя странными ошибками в Xcode beta 5
, Я хотел бы, чтобы кто-то с предыдущей бета-версией Xcode мог подтвердить, прав я или нет. Я также мог что-то неправильно понять, поэтому буду признателен за любые отзывы.
Вот пример кода, который заставил меня некоторое время бороться:
// Frist bug
protocol SomeProtocol {
var someArray: [String] { get set } // #1 bug
}
extension SomeProtocol {
func someFunction(someString: String) {
self.someArray.append(someString) // #1: Immutable value of type '[String]' only has mutating members named 'append'
}
}
// Second bug
protocol SomeInterfaceProtocol {
var someBool: Bool { get set } // #2 bug
}
class SomeClass: SomeInterfaceProtocol {
var someBool: Bool = false
func returnInterface() -> SomeInterfaceProtocol {
return self
}
}
let someInstance = SomeClass()
// can't set the value
someInstance.returnInterface().someBool = true // #2: Cannot assign to property: function call returns immutable value
2 ответа
Первая ошибка может быть решена, если вы добавите модификатор mutating
перед объявлением расширения func вот так:
mutating func someFunction(someString: String) {
Я подозреваю, что это изменение в языке.
Другой также озадачивает меня. По крайней мере, вот обходной путь:
var c = someInstance.returnInterface()
c.someBool = true
Я думаю, что второй тоже не является ошибкой по той же причине, по которой вы не можете изменить элемент в словаре напрямую или что вы не можете изменить элемент в словаре. for elem in array { ... }
,
Что-то должно быть сохранено, чтобы иметь возможность изменить это. Поскольку вы возвращаете тип протокола, компилятор не может знать, является ли он структурой или классом, тогда как, если это структура, операция ее изменения не будет иметь никакого эффекта, поскольку она не сохраняется ни в коем случае и структуры не передаются. по ссылке. Вот почему обходной путь Томаса работает. Возможно, это будет работать, если returnInterface вернул экземпляр класса, а не тип протокола.
РЕДАКТИРОВАТЬ: Просто попробовал: действительно, это работает, если вы вернетесь SomeClass
вместо SomeInterfaceProtocol
или если вы измените протокол на протокол класса, так как он не может быть структурой
protocol SomeInterfaceProtocol : class {
var someBool: Bool { get set }
}
class SomeClass: SomeInterfaceProtocol {
var someBool: Bool = false
func returnInterface() -> SomeInterfaceProtocol {
return self
}
}
или же
protocol SomeInterfaceProtocol {
var someBool: Bool { get set }
}
class SomeClass: SomeInterfaceProtocol {
var someBool: Bool = false
func returnInterface() -> SomeClass {
return self
}
}
обе работают