Swift 2.0 beta:协议是否在 Xcode beta 5 中被破坏了?
Swift 2.0 beta: are protocols kinda broken in 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
如果在扩展函数声明之前添加修饰符 mutating
可以解决第一个错误,如下所示:
mutating func someFunction(someString: String) {
我怀疑这是语言的变化。
另一个我也很疑惑。至少,这里有一个解决方法:
var c = someInstance.returnInterface()
c.someBool = true
我认为第二个也不是错误,原因与您不能直接修改字典中的项目或不能更改 for elem in array { ... }
中的元素相同。
必须保存某些内容才能进行更改。因为您正在 returning 协议类型,所以编译器无法知道它是结构还是 class,而如果它是结构,则更改它的操作将无效,因为它不会持久化以任何方式和结构不通过引用传递。这就是 Thomas 的解决方法起作用的原因。如果 returnInterface returned 一个 class 实例,而不是协议类型,也许它也会起作用。
编辑:刚刚试了一下:事实上,如果你 return SomeClass
而不是 SomeInterfaceProtocol
或者你将协议更改为 class 协议,它确实有效,因为它不能是结构
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
}
}
两者都有效
目前我正在开发使用 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
如果在扩展函数声明之前添加修饰符 mutating
可以解决第一个错误,如下所示:
mutating func someFunction(someString: String) {
我怀疑这是语言的变化。
另一个我也很疑惑。至少,这里有一个解决方法:
var c = someInstance.returnInterface()
c.someBool = true
我认为第二个也不是错误,原因与您不能直接修改字典中的项目或不能更改 for elem in array { ... }
中的元素相同。
必须保存某些内容才能进行更改。因为您正在 returning 协议类型,所以编译器无法知道它是结构还是 class,而如果它是结构,则更改它的操作将无效,因为它不会持久化以任何方式和结构不通过引用传递。这就是 Thomas 的解决方法起作用的原因。如果 returnInterface returned 一个 class 实例,而不是协议类型,也许它也会起作用。
编辑:刚刚试了一下:事实上,如果你 return SomeClass
而不是 SomeInterfaceProtocol
或者你将协议更改为 class 协议,它确实有效,因为它不能是结构
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
}
}
两者都有效