Swift: Failed to Assign Value to a Property of Protocol

Swift: Failed to assign value to a property of protocol?

You have to define the protocol as a class protocol:

protocol ValueProvider : class {
var value: String {get set}
}

Then

var value: String {
get { return v.value }
set { v.value = newValue }
}

compiles and works as expected (i.e. assigns the new value to the
object referenced by v1 if v1 != nil, and to the object
referenced by v2 otherwise).

v is a read-only computed property of the type ValueProvider.
By defining the protocol as a class protocol the compiler knows
that v is a reference type, and therefore its v.value
property can be modified even if the reference itself is a constant.

Your initial code example works because there the v property has
the type A which is a reference type.

And your workaround

set {
var tmp = v1 ?? v2
tmp.value = newValue
}

works because (read-write) properties of variables can be set in
any case (value type or reference type).

Swift protocol settable property through a read-only property

Change your protocol declaration to this:

protocol AProtocol:class {
var name: String { get set }
}

Otherwise, it is taken by default as a value type. Changing a value type's property replaces the value type instance (as shown by the setter observer). And you can't do that if the reference is a let reference.

Specify a settable property/variable in a protocol

The protocol might be implemented by either classes and structs - that prevents you from changing the internal status of an instance of a class or struct implementing that protocol using an immutable variable.

To fix the problem you have to either declare the food variable as mutable:

func eat() {
var food = nextItem
food.eaten = true // (!) ERROR: Cannot assign to result of this expression
}

or declare the EdibleThing protocol to be implementable by classes only:

protocol EdibleThing : class {
var eaten: Bool { get set }
}

Note that this happens because food is a variable of EdibleThing type - the compiler doesn't know if the actual instance is a value or reference type, so it raises an error. If you make it a variable of a class type, like this:

let food: Pickle = nextItem as! Pickle

the compiler knows without any ambiguity that it's a reference type, and in that case it allows the assignment. But I guess that breaks your app logic... so consider it just as an example

Cannot assign to generic property in protocol

You can do it like this

//: Playground - noun: a place where people can play

import Cocoa

protocol StringIdentifiable {
var id: String? { get }
}

protocol Foo: class {
associatedtype AnyStringIdentifiable: StringIdentifiable
var entity: AnyStringIdentifiable? { get set }
}

protocol Bar {
//var foo: Foo { get set } // can't do because Foo is generic
associatedtype AnyFoo: Foo
var foo: AnyFoo { get set }
}

extension Bar {
func setEntity(_ entity: AnyFoo.AnyStringIdentifiable) {
foo.entity = entity
}
}

Within Bar you can use AnyFoo.AnyStringIdentifiable to make sure the types are correct when setting foo.entity, because foo.entity is of the type AnyFoo.AnyStringIdentifiable.

Cannot set value conforming to protocol to property with protocol type

You need to remove the files from your test target since you're already importing your whole project with @testable.

Cannot assign to property in protocol constrained to class - Swift compiler error

In the first case it should be considered an "unimplemented feature" (that the compiler cannot infer the behavior of a class in this context). So to fix it you have to make the value a var:

func afterViewInstantiated <V : ViewForViewModel where V: UIViewController, V.ViewModelType: AnyObject>(var view : V, viewModel: V.ViewModelType) -> V

In the second case you should provide more information about the error (message) and the types. Where does V come from?

Cannot assign to property: 'point' is a 'let' constant

PointType as a protocol, as written, could apply to either a value type (such as a struct) or a reference type (such as a class). If it were a value type and passed to your function without inout, it would be immutable.

If your PointType is always going to be a reference type (and thus always mutable from inside a function where it's pointed to by reference), you can fix your error by saying that it has to be AnyObject:

protocol PointType : AnyObject {


Related Topics



Leave a reply



Submit