无法在协议中分配属性 - Swift编译器错误

时间:2014-12-02 03:34:05

标签: ios swift

我在Swift中使用以下代码将头撞到墙上。我已经定义了一个简单的协议:

protocol Nameable {
    var name : String { get set }
}

并通过以下方式实现:

class NameableImpl : Nameable {
    var name : String = ""
}

然后我在另一个文件中有以下方法(不要问我为什么):

func nameNameable( nameable: Nameable, name: String ) {
    nameable.name = name
}

问题是编译器在此方法中为属性赋值提供了以下错误:

  

无法分配到' name'在&name;'

我无法看到我做错了什么......以下代码编译得很好:

var nameable : Nameable = NameableImpl()
nameable.name = "John"

我确定这件事情我已经被忽视了 - 我做错了什么?

3 个答案:

答案 0 :(得分:90)

@ matt's anwer是正确的。

另一种解决方案是将Nameable声明为class only protocol

protocol Nameable: class {
//               ^^^^^^^ 
    var name : String { get set }
}

我认为,这种解决方案更适合这种情况。由于nameNameablenameable的实例,因此class无效。

答案 1 :(得分:36)

这是因为,Nameable是一个协议,Swift不知道你的函数的Nameable是什么的(风味)。它可能是一个类实例,当然 - 但它可能是一个struct实例。并且无法分配给常量struct 的属性,如下例所示:

struct NameableStruct : Nameable {
    var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign

嗯,默认情况下,传入的函数参数一个常量 - 就像你在说let之前在函数声明中说过nameable一样。< / p>

解决方案是使此参数成为常量:

func nameNameable(var nameable: Nameable, name: String ) {
                  ^^^

注意更高版本的Swift取消了var函数参数表示法,因此您可以通过将常量赋值给变量来完成相同的操作:

protocol Nameable {
    var name : String { get set }
}
func nameNameable(nameable: Nameable, name: String) {
    var nameable = nameable // can't compile without this line
    nameable.name = name
}

答案 2 :(得分:0)

在这里,我编写了一些代码,可能会对关联泛型类型用法有所了解:

protocol NumaricType 
{
   typealias elementType
   func plus(lhs : elementType, _ rhs : elementType) -> elementType
   func minus(lhs : elementType, _ rhs : elementType) -> elementType
}

struct Arthamatic :NumaricType {

func addMethod(element1 :Int, element2 :Int) -> Int {
   return plus(element1, element2)
}
func minusMethod(ele1 :Int, ele2 :Int) -> Int {
    return minus(ele1, ele2)
}
typealias elementType = Int

func plus(lhs: elementType,  _ rhs: elementType) -> elementType {
    return lhs + rhs
}
func minus(lhs: elementType, _ rhs: elementType) -> elementType {
    return lhs - rhs
 }
}
 **Output:**
let obj =  Arthamatic().addMethod(34, element2: 45) // 79