3

以下代码:

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()解决错误。

主题。

4

2 回答 2

5

除了@Sulthan 所说的之外,还有两种可能的解决方案,具体取决于您的功能需要做什么。

您可以使函数泛型

func doSomethingWith<T : SomeProtocol>(inout someVar: T) {}

现在您可以传递任何符合协议的类的实例:

var someGlobalVar = SomeClass()
doSomethingWith(&someGlobalVar)

如果您只使用的实例并且该函数只修改实例指向的对象的属性,那么您根本不需要 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"
于 2015-08-12T09:35:58.420 回答
3

当您SomeClass在声明时将实例分配给变量时,变量类型被推断为SomeClass. 和写作一样

private var someGlobalVar: SomeClass = SomeClass()

但是,当传递给inout参数时,函数可以为该变量分配另一个实例,例如

private func doSomethingWith(inout someVar: SomeProtocol) {
    someVar = OtherClass()
}

现在你有一个类型不匹配。您看到的错误是 Swift 阻止您遇到类似问题。

换句话说:如果您将一个变量传递给一个函数并且您知道该函数可以将任何采用该变量的实例分配SomeProtocol给该变量,则您必须使用一个实际上可以容纳任何采用该实例的变量SomeProtocol

private var someGlobalVar: SomeProtocol
于 2015-08-12T09:02:29.893 回答