无法赋值,Swift treat是不可变的

无法赋值,Swift treat是不可变的,swift,Swift,我有协议: protocol CellLineDrawing : Any { var isShouldDrawBottomLine : Bool { get set } var isShouldDrawUpperLine : Bool { get set } } var arrValues : [Any]! func drawLinesIfNeeded () -> Void { guard arrValues!.count > 0 else {

我有协议:

protocol CellLineDrawing : Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
var arrValues : [Any]!


func drawLinesIfNeeded () -> Void {

    guard arrValues!.count > 0 else {
        print("Empty array")
        return
    }

    guard arrValues!.first is CellLineDrawing else {
        print("Does not conform to cell line drawing protocol")
        return
    }

    var firstModel = arrValues.first
    var lastModel = arrValues.last

    (firstModel as! CellLineDrawing).isShouldDrawUpperLine = true //ERROR - Cannot assign to immutable expression of type 'Bool'




}
protocol CellLineDrawing : class, Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
然后我尝试将值设置为符合协议的对象:

protocol CellLineDrawing : Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
var arrValues : [Any]!


func drawLinesIfNeeded () -> Void {

    guard arrValues!.count > 0 else {
        print("Empty array")
        return
    }

    guard arrValues!.first is CellLineDrawing else {
        print("Does not conform to cell line drawing protocol")
        return
    }

    var firstModel = arrValues.first
    var lastModel = arrValues.last

    (firstModel as! CellLineDrawing).isShouldDrawUpperLine = true //ERROR - Cannot assign to immutable expression of type 'Bool'




}
protocol CellLineDrawing : class, Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
表达式
(firstModel as!CellLineDrawing)
是一个常量, 并且不能改变它的属性(除非它是 引用类型)

除非我弄错了,否则您需要一个临时变量:

if var firstModel = arrValues.first as? CellLineDrawing {
    firstModel.isShouldDrawUpperLine = true
    arrValues[0] = firstModel
}
表达式
(firstModel as!CellLineDrawing)
是一个常量, 并且不能改变它的属性(除非它是 引用类型)

除非我弄错了,否则您需要一个临时变量:

if var firstModel = arrValues.first as? CellLineDrawing {
    firstModel.isShouldDrawUpperLine = true
    arrValues[0] = firstModel
}

只有当
firstModel
是一个类的实例并且Swift知道它是一个类的实例时,您的作业才有效

如果您的
firstModel
始终是类的实例,则可以通过更改协议使代码正常工作

因为您的协议没有标记
,Swift认为它可以应用于
结构
。因此,
(firstModel as!cellllinedrawing)
被视为不可变的,因为如果项是一个结构,它将是不可变的

通过向协议中添加

protocol CellLineDrawing : Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
var arrValues : [Any]!


func drawLinesIfNeeded () -> Void {

    guard arrValues!.count > 0 else {
        print("Empty array")
        return
    }

    guard arrValues!.first is CellLineDrawing else {
        print("Does not conform to cell line drawing protocol")
        return
    }

    var firstModel = arrValues.first
    var lastModel = arrValues.last

    (firstModel as! CellLineDrawing).isShouldDrawUpperLine = true //ERROR - Cannot assign to immutable expression of type 'Bool'




}
protocol CellLineDrawing : class, Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
您告诉Swift该协议只能应用于对象实例。在这种情况下,该项可能会发生变异

(firstModel as! CellLineDrawing).isShouldDrawUpperLine = true // this now works


如果您的
firstModel
可以是
struct
的实例,则您必须创建该项的可变副本,对其进行更改,然后将其复制回。请参阅。

只有当
firstModel
是一个类的实例并且Swift知道它是一个类的实例时,您的作业才有效

如果您的
firstModel
始终是类的实例,则可以通过更改协议使代码正常工作

因为您的协议没有标记
,Swift认为它可以应用于
结构
。因此,
(firstModel as!cellllinedrawing)
被视为不可变的,因为如果项是一个结构,它将是不可变的

通过向协议中添加

protocol CellLineDrawing : Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
var arrValues : [Any]!


func drawLinesIfNeeded () -> Void {

    guard arrValues!.count > 0 else {
        print("Empty array")
        return
    }

    guard arrValues!.first is CellLineDrawing else {
        print("Does not conform to cell line drawing protocol")
        return
    }

    var firstModel = arrValues.first
    var lastModel = arrValues.last

    (firstModel as! CellLineDrawing).isShouldDrawUpperLine = true //ERROR - Cannot assign to immutable expression of type 'Bool'




}
protocol CellLineDrawing : class, Any {
    var isShouldDrawBottomLine : Bool { get set  }
    var isShouldDrawUpperLine : Bool { get set }
}
您告诉Swift该协议只能应用于对象实例。在这种情况下,该项可能会发生变异

(firstModel as! CellLineDrawing).isShouldDrawUpperLine = true // this now works



如果您的
firstModel
可以是
struct
的实例,则您必须创建该项的可变副本,对其进行更改,然后将其复制回。请参阅。

@MartinR我们应该知道的所有元素都是Any类型的,并且符合协议。您使用
[Any]的理由真的很充分吗这里?(对于初学者来说,它可能不应该是隐式展开的可选选项)。你真的能在里面放点什么吗?看起来你只是想要一个[
CellLineDrawing
].@Hamish我不想显式设置对象的类型,那是我的point@MartinR我们应该知道的所有元素都是Any类型的,并且符合协议。您使用
[Any]的理由真的很充分吗这里?(对于初学者来说,它可能不应该是隐式展开的可选选项)。你真的能在里面放点什么吗?看起来你只是想要一个[
CellLineDrawing
].@Hamish我不想显式设置对象的类型,这是我的观点谢谢,但为什么它是常量?Obj-C中的相同语法将很好地工作。@EvgeniyKleban:您在Objective-C中的“相同语法”是什么?你确定你不是在处理引用吗?我是说圆括号,我用它来转换对象。@EvgeniyKleban:不一般。但是
firstModel作为!CellLineDrawing
是一个不可变的表达式。它创建了一个CellLineDrawing类型的新值。@EvgeniyKleban:它的属性是可变的,但如果您有一个常量值,这就没有帮助了。谢谢,但为什么它是常量?Obj-C中的相同语法将很好地工作。@EvgeniyKleban:您在Objective-C中的“相同语法”是什么?你确定你不是在处理引用吗?我是说圆括号,我用它来转换对象。@EvgeniyKleban:不一般。但是
firstModel作为!CellLineDrawing
是一个不可变的表达式。它创建了一个CellLineDrawing类型的新值。@EvgeniyKleban:它的属性是可变的,但如果您有一个常量值,这并没有帮助。@vacawama感谢您的帮助,但这并不能解决问题,您可以在操场上随意尝试,并随时查看yourself@EvgeniyKleban:如果实际实例是引用类型,那么这也应该解决您的问题(这就是我在现已删除的注释中建议的原因)“Any”应该是引用类型还是命名类型?@EvgeniyKleban,
firstModel
类的实例还是
结构的实例struct@vacawama谢谢你的帮助,但这并不能解决问题,你可以在操场上试一下,顺便看看yourself@EvgeniyKleban:如果实际实例是引用类型,那么这也可以解决您的问题(这就是为什么我在一条现已删除的评论中建议它的原因)“Any”应该是引用类型还是命名类型?@EvgeniyKleban,
firstModel
类的实例还是
结构的实例