"Cannot assign to the result of this expression" 变量 (var) 引起的错误
"Cannot assign to the result of this expression" error arising from a variable (var)
我定义了以下子class,其主要 属性 链接到一个枚举:
let NumberOfColors: UInt32 = 6
enum SphereColor: Int, Printable {
case Red = 0, Yellow, Blue, Green, Purple, White
var sphereName: String {
switch self {
case .Red:
return "red"
case .Yellow:
return "yellow"
case .Blue:
return "blue"
case .Green:
return "green"
case .Purple:
return "purple"
case .White:
return "white"
}
}
var description: String {
return self.sphereName
}
static func random() -> SphereColor {
return SphereColor(rawValue: Int(arc4random_uniform(NumberOfColors - 1)))!
}
}
class Sphere: SCNSphere {
var color : SphereColor
init(radius: CGFloat, color: SphereColor) {
self.color = color
super.init()
switch color.rawValue as Int {
case 0:
self.firstMaterial?.diffuse.contents = UIColor.redColor()
case 1:
self.firstMaterial?.diffuse.contents = UIColor.yellowColor()
case 2:
self.firstMaterial?.diffuse.contents = UIColor.blueColor()
case 3:
self.firstMaterial?.diffuse.contents = UIColor.greenColor()
case 4:
self.firstMaterial?.diffuse.contents = UIColor.purpleColor()
case 5:
self.firstMaterial?.diffuse.contents = UIColor.whiteColor()
default:
break
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
实例化使用
let sphere = Sphere(radius: radius, color: SphereColor.random())
let sphereNode = SCNNode(geometry: sphere)
工作正常,但是当我 select 其中一个节点并尝试将其颜色 属性 更改为
// node selection...
var geom = node.geometry! as! Sphere
geom.color.rawValue = 5
我收到 "Cannot assign to the result of this expression" 错误,但我没有将颜色 属性 声明为常量并且不明白为什么会这样。我假设我在与 Sphere class 相关的代码中犯了一些基本错误,关于这可能是什么的任何想法?
编辑:使用
geom.color = SphereColor(rawValue: 5)!
正如 Martin R 所说,允许我构建和 运行 我的代码,但球体的颜色没有改变,这让我觉得我的 subclass 声明仍然有问题.
rawValue
是只读的 属性,您不能分配新值
给它。您必须从 SphereColor
创建一个
原始值并将其分配给 color
属性:
geom.color = SphereColor(rawValue: 5)!
或者如果有 任何 可能原始值可能超出范围
并且不存在匹配的颜色:
if let color = SphereColor(rawValue: 5) {
geom.color = color
}
支持@MartinR 解决第一个问题,但我对其余问题的回应太大而无法发表评论。
如前所述,rawValue
是枚举的只读 属性。枚举是 value types,因此您不会更改枚举的 "instance" 的值,而是创建一个新值。 (将枚举想象成花哨的数字。您不会将 7 本身 更改为另一个数字,而是将保存值 7 的变量更改为保存另一个值。)从相应的原始类型,使用 init(rawValue:)
初始值设定项。
你的第二个问题是你正在更新模型(以概念/语义的方式告诉你你认为你的球是什么颜色的部分)但是你正在设置该模型的视觉表示( SceneKit 的东西你可以看到)只有当你创建一个 Sphere
时,而不是当你设置它的 color
属性 时。如果你想保持模型和视图同步,你需要做到这一点。
您已经在初始化程序中拥有将 Color
转换为 SceneKit material 颜色的代码。考虑到这一点,这样您也可以从其他地方调用它,然后您可以在模型发生变化时使用它来更新您的视图——比如,使用 property observer.
除此之外还有一些其他改进:
class Sphere: SCNSphere {
func setMaterialColor(sphereColor: SphereColor) {
let color: UIColor
// Switch on the enum, not the int.
// That way the compiler can check exhaustiveness,
// and you don't need a dead default case.
switch sphereColor {
case .Red:
// Use a temporary for the color choice so
// you're only setting the material property once.
color = UIColor.redColor()
case .Yellow:
color = UIColor.yellowColor()
case .Blue:
color = UIColor.blueColor()
case .Green:
color = UIColor.greenColor()
case .Purple:
color = UIColor.purpleColor()
case .White:
color = UIColor.whiteColor()
}
// Force-unwrap firstMaterial -- we "know" it should be non-nil,
// so it's better to find out the hard way if something weird has happened.
// (Either that or test the optional so you can manage failure specifically.)
self.firstMaterial!.diffuse.contents = color
}
var color : SphereColor {
didSet {
self.setMaterialColor(color)
}
}
init(radius: CGFloat, color: SphereColor) {
self.color = color
super.init()
self.setMaterialColor(color)
}
required init(coder aDecoder: NSCoder) { /* ... */ }
}
我定义了以下子class,其主要 属性 链接到一个枚举:
let NumberOfColors: UInt32 = 6
enum SphereColor: Int, Printable {
case Red = 0, Yellow, Blue, Green, Purple, White
var sphereName: String {
switch self {
case .Red:
return "red"
case .Yellow:
return "yellow"
case .Blue:
return "blue"
case .Green:
return "green"
case .Purple:
return "purple"
case .White:
return "white"
}
}
var description: String {
return self.sphereName
}
static func random() -> SphereColor {
return SphereColor(rawValue: Int(arc4random_uniform(NumberOfColors - 1)))!
}
}
class Sphere: SCNSphere {
var color : SphereColor
init(radius: CGFloat, color: SphereColor) {
self.color = color
super.init()
switch color.rawValue as Int {
case 0:
self.firstMaterial?.diffuse.contents = UIColor.redColor()
case 1:
self.firstMaterial?.diffuse.contents = UIColor.yellowColor()
case 2:
self.firstMaterial?.diffuse.contents = UIColor.blueColor()
case 3:
self.firstMaterial?.diffuse.contents = UIColor.greenColor()
case 4:
self.firstMaterial?.diffuse.contents = UIColor.purpleColor()
case 5:
self.firstMaterial?.diffuse.contents = UIColor.whiteColor()
default:
break
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
实例化使用
let sphere = Sphere(radius: radius, color: SphereColor.random())
let sphereNode = SCNNode(geometry: sphere)
工作正常,但是当我 select 其中一个节点并尝试将其颜色 属性 更改为
// node selection...
var geom = node.geometry! as! Sphere
geom.color.rawValue = 5
我收到 "Cannot assign to the result of this expression" 错误,但我没有将颜色 属性 声明为常量并且不明白为什么会这样。我假设我在与 Sphere class 相关的代码中犯了一些基本错误,关于这可能是什么的任何想法?
编辑:使用
geom.color = SphereColor(rawValue: 5)!
正如 Martin R 所说,允许我构建和 运行 我的代码,但球体的颜色没有改变,这让我觉得我的 subclass 声明仍然有问题.
rawValue
是只读的 属性,您不能分配新值
给它。您必须从 SphereColor
创建一个
原始值并将其分配给 color
属性:
geom.color = SphereColor(rawValue: 5)!
或者如果有 任何 可能原始值可能超出范围 并且不存在匹配的颜色:
if let color = SphereColor(rawValue: 5) {
geom.color = color
}
支持@MartinR 解决第一个问题,但我对其余问题的回应太大而无法发表评论。
如前所述,rawValue
是枚举的只读 属性。枚举是 value types,因此您不会更改枚举的 "instance" 的值,而是创建一个新值。 (将枚举想象成花哨的数字。您不会将 7 本身 更改为另一个数字,而是将保存值 7 的变量更改为保存另一个值。)从相应的原始类型,使用 init(rawValue:)
初始值设定项。
你的第二个问题是你正在更新模型(以概念/语义的方式告诉你你认为你的球是什么颜色的部分)但是你正在设置该模型的视觉表示( SceneKit 的东西你可以看到)只有当你创建一个 Sphere
时,而不是当你设置它的 color
属性 时。如果你想保持模型和视图同步,你需要做到这一点。
您已经在初始化程序中拥有将 Color
转换为 SceneKit material 颜色的代码。考虑到这一点,这样您也可以从其他地方调用它,然后您可以在模型发生变化时使用它来更新您的视图——比如,使用 property observer.
除此之外还有一些其他改进:
class Sphere: SCNSphere {
func setMaterialColor(sphereColor: SphereColor) {
let color: UIColor
// Switch on the enum, not the int.
// That way the compiler can check exhaustiveness,
// and you don't need a dead default case.
switch sphereColor {
case .Red:
// Use a temporary for the color choice so
// you're only setting the material property once.
color = UIColor.redColor()
case .Yellow:
color = UIColor.yellowColor()
case .Blue:
color = UIColor.blueColor()
case .Green:
color = UIColor.greenColor()
case .Purple:
color = UIColor.purpleColor()
case .White:
color = UIColor.whiteColor()
}
// Force-unwrap firstMaterial -- we "know" it should be non-nil,
// so it's better to find out the hard way if something weird has happened.
// (Either that or test the optional so you can manage failure specifically.)
self.firstMaterial!.diffuse.contents = color
}
var color : SphereColor {
didSet {
self.setMaterialColor(color)
}
}
init(radius: CGFloat, color: SphereColor) {
self.color = color
super.init()
self.setMaterialColor(color)
}
required init(coder aDecoder: NSCoder) { /* ... */ }
}