协议类型的 inout 变量是不是被禁止?
Posted
技术标签:
【中文标题】协议类型的 inout 变量是不是被禁止?【英文标题】:Are inout variables of protocol type prohibited?协议类型的 inout 变量是否被禁止? 【发布时间】:2015-08-12 08:39:43 【问题描述】:以下代码:
protocol SomeProtocol
class SomeClass: SomeProtocol
private func doSomethingWith(inout someVar: SomeProtocol)
private var someGlobalVar = SomeClass() // inferring SomeClass's type
doSomethingWith(&someGlobalVar)
产生以下错误:
无法使用“(inout SomeClass)”类型的参数列表调用“doSomethingWith”
将倒数第二行更改为private var someGlobalVar: SomeProtocol = SomeClass()
可解决错误。
主题
【问题讨论】:
我很惊讶这个问题没有更多的观点!似乎更多的人会遇到......再一次,也许人们不再通过带有协议参数的函数来改变对象。 :) @RayToal 可能是因为inout
变量在设计架构时并不是很受欢迎的选择;)
没错,而且是为了更好。纯类协议很好地解决了这个问题,但并不明显。
【参考方案1】:
除了@Sulthan 说的,还有两种可能的解决方案, 取决于您的功能需要做什么。
你可以使函数通用:
func doSomethingWith<T : SomeProtocol>(inout someVar: T)
现在您可以传递任何符合协议的类的实例:
var someGlobalVar = SomeClass()
doSomethingWith(&someGlobalVar)
如果你只使用 class 的实例并且只使用函数 修改实例指向的对象的属性,那么您根本不需要 inout 参数,因为类是引用类型。 您只需要将协议标记为“类协议”:
protocol SomeProtocol : class
var name : String get set
class SomeClass: SomeProtocol
var name : String = ""
func doSomethingWith(someVar: SomeProtocol)
// Modify the object:
someVar.name = "modfied"
var someGlobalVar = SomeClass()
doSomethingWith(someGlobalVar)
print(someGlobalVar.name) // "modified"
【讨论】:
【参考方案2】:当您在声明时将SomeClass
实例分配给变量时,变量类型被推断为SomeClass
。和写一样
private var someGlobalVar: SomeClass = SomeClass()
但是,当传递给inout
参数时,函数可以为该变量分配另一个实例,例如
private func doSomethingWith(inout someVar: SomeProtocol)
someVar = OtherClass()
现在你有一个类型不匹配。您看到的错误是 Swift 阻止您遇到类似问题。
换句话说:如果您将变量传递给函数并且您知道该函数可以将采用SomeProtocol
的任何实例分配给该变量,那么您必须使用一个实际上可以容纳任何采用SomeProtocol
的实例的变量:
private var someGlobalVar: SomeProtocol
【讨论】:
以上是关于协议类型的 inout 变量是不是被禁止?的主要内容,如果未能解决你的问题,请参考以下文章
FPGA中的inout类型的数据在引脚分配的时候与input和output类型有区别吗?望高手赐教!
无法使用类型为 '(inout inout $T6, inout inout$T11) 的参数列表调用 'subscript'
swift 无法将类型“[Liquor]”的值转换为预期的参数类型“inout _”
无法将“Int”类型的值转换为预期的参数类型“(inout UnsafeMutableBufferPointer<_>, inout Int) throws -> Void”