Подтвердить что ты не робот

Невозможно назначить свойство в протоколе - ошибка компилятора Swift

Я стучу головой о стену со следующим кодом в Свифте. Я определил простой протокол:

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

и реализовано с помощью:

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

а затем у меня есть следующий метод в другом файле (не спрашивайте меня почему):

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

Проблема заключается в том, что компилятор дает следующую ошибку для присвоения свойства в этом методе:

не может назначить 'name' в 'nameable'

Я не вижу, что я делаю неправильно... Следующий код компилируется отлично:

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

Я уверен, что это простое, что я забыл - что я делаю неправильно?

4b9b3361

Ответ 1

@matt anwer правильный.

Другое решение - объявить Nameable как class только протокол.

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

Я думаю, что это решение более подходит для этого случая. Поскольку nameNameable бесполезен, если Nameable не является экземпляром class.

Ответ 2

Это потому, что, Nameable является протоколом, Swift не знает, какой тип (аромат) объекта имеет ваша функция, входящая в Nameable. Это может быть экземпляр класса, конечно - но это может быть экземпляр структуры. И вы не можете назначить свойство постоянной структуры, как показано в следующем примере:

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

Ну, по умолчанию параметр входящей функции является константой - это точно так, как если бы вы сказали let в своем объявлении функции, прежде чем сказали nameable.

Решение состоит в том, чтобы сделать этот параметр не постоянным:

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

Ответ 3

Здесь я написал код, который может дать некоторое представление об ассоциированном родовом типе. Использование:

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