Cannot assign to property in protocol - Swift compiler error
I'm banging my head against the wall with the following code in Swift. I've defined a simple protocol:
protocol Nameable {
var name : String { get set }
}
and implemented that with:
class NameableImpl : Nameable {
var name : String = ""
}
and then I have the following method in another file (don't ask me why):
func nameNameable( nameable: Nameable, name: String ) {
nameable.name = name
}
The problem is that the compiler gives the following error for the property assignment in this method:
cannot assign to 'name' in 'nameable'
I can't see what I'm doing wrong... The following code compiles fine:
var nameable : Nameable = NameableImpl()
nameable.name = "John"
I'm sure it's something simple I've overlooked - what am I doing wrong?
ios swift
add a comment |
I'm banging my head against the wall with the following code in Swift. I've defined a simple protocol:
protocol Nameable {
var name : String { get set }
}
and implemented that with:
class NameableImpl : Nameable {
var name : String = ""
}
and then I have the following method in another file (don't ask me why):
func nameNameable( nameable: Nameable, name: String ) {
nameable.name = name
}
The problem is that the compiler gives the following error for the property assignment in this method:
cannot assign to 'name' in 'nameable'
I can't see what I'm doing wrong... The following code compiles fine:
var nameable : Nameable = NameableImpl()
nameable.name = "John"
I'm sure it's something simple I've overlooked - what am I doing wrong?
ios swift
add a comment |
I'm banging my head against the wall with the following code in Swift. I've defined a simple protocol:
protocol Nameable {
var name : String { get set }
}
and implemented that with:
class NameableImpl : Nameable {
var name : String = ""
}
and then I have the following method in another file (don't ask me why):
func nameNameable( nameable: Nameable, name: String ) {
nameable.name = name
}
The problem is that the compiler gives the following error for the property assignment in this method:
cannot assign to 'name' in 'nameable'
I can't see what I'm doing wrong... The following code compiles fine:
var nameable : Nameable = NameableImpl()
nameable.name = "John"
I'm sure it's something simple I've overlooked - what am I doing wrong?
ios swift
I'm banging my head against the wall with the following code in Swift. I've defined a simple protocol:
protocol Nameable {
var name : String { get set }
}
and implemented that with:
class NameableImpl : Nameable {
var name : String = ""
}
and then I have the following method in another file (don't ask me why):
func nameNameable( nameable: Nameable, name: String ) {
nameable.name = name
}
The problem is that the compiler gives the following error for the property assignment in this method:
cannot assign to 'name' in 'nameable'
I can't see what I'm doing wrong... The following code compiles fine:
var nameable : Nameable = NameableImpl()
nameable.name = "John"
I'm sure it's something simple I've overlooked - what am I doing wrong?
ios swift
ios swift
edited Dec 2 '14 at 3:53
matt
326k46526725
326k46526725
asked Dec 2 '14 at 3:34
olensmarolensmar
299135
299135
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
@matt's anwer is correct.
Another solution is to declare Nameable
as a class
only protocol.
protocol Nameable: class {
// ^^^^^^^
var name : String { get set }
}
I think, this solution is more suitable for this case. Because nameNameable
is useless unless nameable
is a instance of class
.
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but addingclass
solved everything.
– Mike
Oct 2 '15 at 1:37
1
Why does this work, but notprotocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.
– GoldenJoe
Nov 15 '17 at 6:59
add a comment |
It's because, Nameable being a protocol, Swift doesn't know what kind (flavor) of object your function's incoming Nameable is. It might be a class instance, sure - but it might be a struct instance. And you can't assign to a property of a constant struct, as the following example demonstrates:
struct NameableStruct : Nameable {
var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign
Well, by default, an incoming function parameter is a constant - it is exactly as if you had said let
in your function declaration before you said nameable
.
The solution is to make this parameter not be a constant:
func nameNameable(var nameable: Nameable, name: String ) {
^^^
NOTE Later versions of Swift have abolished the var
function parameter notation, so you'd accomplish the same thing by assigning the constant to a variable:
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
}
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting erroruse of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
add a comment |
Here, i written some code, that might give some idea on Associated generic type Usage:
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
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f27241411%2fcannot-assign-to-property-in-protocol-swift-compiler-error%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
@matt's anwer is correct.
Another solution is to declare Nameable
as a class
only protocol.
protocol Nameable: class {
// ^^^^^^^
var name : String { get set }
}
I think, this solution is more suitable for this case. Because nameNameable
is useless unless nameable
is a instance of class
.
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but addingclass
solved everything.
– Mike
Oct 2 '15 at 1:37
1
Why does this work, but notprotocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.
– GoldenJoe
Nov 15 '17 at 6:59
add a comment |
@matt's anwer is correct.
Another solution is to declare Nameable
as a class
only protocol.
protocol Nameable: class {
// ^^^^^^^
var name : String { get set }
}
I think, this solution is more suitable for this case. Because nameNameable
is useless unless nameable
is a instance of class
.
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but addingclass
solved everything.
– Mike
Oct 2 '15 at 1:37
1
Why does this work, but notprotocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.
– GoldenJoe
Nov 15 '17 at 6:59
add a comment |
@matt's anwer is correct.
Another solution is to declare Nameable
as a class
only protocol.
protocol Nameable: class {
// ^^^^^^^
var name : String { get set }
}
I think, this solution is more suitable for this case. Because nameNameable
is useless unless nameable
is a instance of class
.
@matt's anwer is correct.
Another solution is to declare Nameable
as a class
only protocol.
protocol Nameable: class {
// ^^^^^^^
var name : String { get set }
}
I think, this solution is more suitable for this case. Because nameNameable
is useless unless nameable
is a instance of class
.
edited Dec 2 '14 at 4:05
answered Dec 2 '14 at 3:59
rintarorintaro
42.3k8108122
42.3k8108122
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but addingclass
solved everything.
– Mike
Oct 2 '15 at 1:37
1
Why does this work, but notprotocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.
– GoldenJoe
Nov 15 '17 at 6:59
add a comment |
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but addingclass
solved everything.
– Mike
Oct 2 '15 at 1:37
1
Why does this work, but notprotocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.
– GoldenJoe
Nov 15 '17 at 6:59
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
My appreciation for Swift just grew bigger because of this.
– Matthew Quiros
May 5 '15 at 9:46
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but adding
class
solved everything.– Mike
Oct 2 '15 at 1:37
This +10000. I was having major issues implementing a protocol and extensions that involved a struct property, and was unable to mutate it without all sorts of headaches, but adding
class
solved everything.– Mike
Oct 2 '15 at 1:37
1
1
Why does this work, but not
protocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.– GoldenJoe
Nov 15 '17 at 6:59
Why does this work, but not
protocol Nameable where Self : UIView
(assuming you just wanted views to inherit this protocol). UIView is a class, but it won't actually get rid of his error.– GoldenJoe
Nov 15 '17 at 6:59
add a comment |
It's because, Nameable being a protocol, Swift doesn't know what kind (flavor) of object your function's incoming Nameable is. It might be a class instance, sure - but it might be a struct instance. And you can't assign to a property of a constant struct, as the following example demonstrates:
struct NameableStruct : Nameable {
var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign
Well, by default, an incoming function parameter is a constant - it is exactly as if you had said let
in your function declaration before you said nameable
.
The solution is to make this parameter not be a constant:
func nameNameable(var nameable: Nameable, name: String ) {
^^^
NOTE Later versions of Swift have abolished the var
function parameter notation, so you'd accomplish the same thing by assigning the constant to a variable:
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
}
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting erroruse of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
add a comment |
It's because, Nameable being a protocol, Swift doesn't know what kind (flavor) of object your function's incoming Nameable is. It might be a class instance, sure - but it might be a struct instance. And you can't assign to a property of a constant struct, as the following example demonstrates:
struct NameableStruct : Nameable {
var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign
Well, by default, an incoming function parameter is a constant - it is exactly as if you had said let
in your function declaration before you said nameable
.
The solution is to make this parameter not be a constant:
func nameNameable(var nameable: Nameable, name: String ) {
^^^
NOTE Later versions of Swift have abolished the var
function parameter notation, so you'd accomplish the same thing by assigning the constant to a variable:
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
}
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting erroruse of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
add a comment |
It's because, Nameable being a protocol, Swift doesn't know what kind (flavor) of object your function's incoming Nameable is. It might be a class instance, sure - but it might be a struct instance. And you can't assign to a property of a constant struct, as the following example demonstrates:
struct NameableStruct : Nameable {
var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign
Well, by default, an incoming function parameter is a constant - it is exactly as if you had said let
in your function declaration before you said nameable
.
The solution is to make this parameter not be a constant:
func nameNameable(var nameable: Nameable, name: String ) {
^^^
NOTE Later versions of Swift have abolished the var
function parameter notation, so you'd accomplish the same thing by assigning the constant to a variable:
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
}
It's because, Nameable being a protocol, Swift doesn't know what kind (flavor) of object your function's incoming Nameable is. It might be a class instance, sure - but it might be a struct instance. And you can't assign to a property of a constant struct, as the following example demonstrates:
struct NameableStruct : Nameable {
var name : String = ""
}
let ns = NameableStruct(name:"one")
ns.name = "two" // can't assign
Well, by default, an incoming function parameter is a constant - it is exactly as if you had said let
in your function declaration before you said nameable
.
The solution is to make this parameter not be a constant:
func nameNameable(var nameable: Nameable, name: String ) {
^^^
NOTE Later versions of Swift have abolished the var
function parameter notation, so you'd accomplish the same thing by assigning the constant to a variable:
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
}
edited Nov 22 '18 at 20:28
answered Dec 2 '14 at 3:40
mattmatt
326k46526725
326k46526725
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting erroruse of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
add a comment |
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting erroruse of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
tl;dr change "let myProtocolConformingItem" to "var myProtocolConformingItem"
– Ilias Karim
May 6 '15 at 21:06
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
@matt While this proposal/solution definitely works and is currently even proposed by the compiler, do you consider it being a code smell?
– damirstuhec
Jan 11 '16 at 6:37
i am getting error
use of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
i am getting error
use of undeclared type of nameable
– Jack
Aug 4 '17 at 14:17
1
1
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack that was years ago! My answer isn't valid Swift syntax nowadays
– matt
Aug 4 '17 at 15:07
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
@Jack added a modernized version of the same answer
– matt
Nov 22 '18 at 20:31
add a comment |
Here, i written some code, that might give some idea on Associated generic type Usage:
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
add a comment |
Here, i written some code, that might give some idea on Associated generic type Usage:
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
add a comment |
Here, i written some code, that might give some idea on Associated generic type Usage:
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
Here, i written some code, that might give some idea on Associated generic type Usage:
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
answered Sep 29 '15 at 6:24
Narendra GNarendra G
34936
34936
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f27241411%2fcannot-assign-to-property-in-protocol-swift-compiler-error%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown