Expression is not assignable (OC为什么不能直接修改结构体属性)!

OC为什么不能直接修改结构体属性

self.image.frame.origin.x = 20;

这样写没法通过编译,编译器会报错"expression is not assignable"

原因是,这句话里面的几个点有两种不同的含义。self.image.frame是Objective-C语法,是读取image属性的frame属性,在Objective-C中使用点来访问属性只是一种语法,所以self.image.frame这句话会被转换成:

[[self image] frame]

也就是说,实际上这是消息传递。

而frame属性是一个CGRect结构,所以frame.origin.x是C语言的语法,就是访问CGRect结构中的origin字段,同样,x是CGOrigin结构的一个字段。所以,你这句话实际上等于:

[[self image] frame].origin.x = 20;

而Objective-C只是对C语言的一个扩展,所以,上面这句话会被转成C语言的函数调用形式,类似于这种形式:

getframe().origin.x = 20;

而在C语言里,函数的返回值是一个R-Value,是不能直接给它赋值的(所谓的R-Value,就是只能出现在等号的右边,你可以理解成是一个常量;而可以被赋值的是L-Value,可以出现在等号的左边,通常是变量)。因此,当你打算直接给函数的返回值赋值的时候,编译器告诉你"这个表达式无法被赋值"。这就是这个错误的出现原因。

所以,解决办法就是,用一个临时变量保存这个函数的返回值,修改这个临时变量,然后再赋给frame:

// 1. 用一个临时变量保存返回值。
CGRect temp = self.image.frame;

// 2. 给这个变量赋值。因为变量都是L-Value,可以被赋值
temp.image.x = 20;

// 3. 修改frame的值
self.image.frame = temp;

看起来三部曲比较麻烦,期待有天,Objective-C的编译器会变的智能一点,自动完成这种转换。

<think>嗯,用户现在问的是“error: expression is not assignable 是什么意思”,看起来他们遇到了编程中的错误提示,需要解释这个错误的原因和解决方法。之前他们问过类似的警告“equality comparison result unused”,所以可能他们正在学习编程,特别是C或类似的语言,因为之前的例子用了C和JavaScript。 首先,我要确定这个错误的具体含义。根据我的知识,“expression is not assignable”通常发生在尝试给一个不可赋的表达式赋候。比如,给常量赋,或者尝试修改(如字面量或临对象)。需要举一些常见的例子,帮助用户理解。 接下来,我需要考虑用户可能的场景。用户可能是在写代码不小心把赋符号用错了,比如把比较运算符写成赋,或者试图修改一个不应该被修改的变量,比如常量或者函数返回。比如他们可能写了类似3 = x;或者数组名作为指针常量尝试赋。 然后,我要考虑用户的需求。他们不仅需要知道错误是什么,还需要知道如何解决。所以需要分点列出常见原因和解决方法,比如检查是否是常量、数组名、函数返回,或者运算符优先级的问题。同,用代码示例说明错误和正确的做法,这样用户更容易理解。 另外,用户之前的问题是关于未使用的比较结果,可能他们混淆了=和==,所以这次可能也是类似的错误,比如在条件语句中错误使用了赋而非比较,或者反过来。需要提醒用户检查运算符的使用是否正确。 还要注意用户可能的深层需求。他们可能对左和右的概念不熟悉,或者对某些语法规则不清楚,所以解释需要简明扼要,避免使用过多术语,但又要准确。比如,解释数组名作为指针常量不可修改,或者函数返回的是临对象而非变量。 最后,总结错误的原因,帮助用户形成系统的理解,避免未来再犯类似错误。确保回答结构清晰,分点明确,代码示例对比错误和正确情况,方便用户对照检查自己的代码。</think> **错误 `error: expression is not assignable` 的含义:** 该错误表示代码中尝试对一个**不可被赋的表达式**进行赋操作(例如使用 `=`、`+=` 等赋运算符)。编译器发现左侧的操作数(左)并非合法的赋目标,导致操作无法完成。 --- ### **常见触发场景及示例** #### 1. **尝试对常量或字面量赋** ```c const int x = 10; x = 20; // 错误:x 是常量,不可赋 3 = 5; // 错误:字面量(如 3)不可作为左 ``` #### 2. **对函数返回或表达式结果赋** ```c int getValue() { return 42; } getValue() = 100; // 错误:函数返回是临(右),无法被赋 (x + 1) = 5; // 错误:表达式 (x + 1) 的结果是临 ``` #### 3. **对数组名直接(数组名是常量指针)** ```c int arr[5]; arr = {1, 2, 3}; // 错误:数组名是常量指针,不可重新赋 ``` #### 4. **运算符优先级问题** ```c *p++ = 10; // 正确:等价于 *(p++) = 10(先赋,再移动指针) *p->field = 5; // 若 p 是结构体指针,需确保语法正确 ``` #### 5. **误用比较运算符 `==` 和赋运算符 `=`** ```c if (x = 5) { ... } // 警告:可能本意是 if (x == 5) // 此处将 x 赋为 5,条件始终为真 ``` --- ### **解决方法** 1. **检查赋目标是否为变量** - 确保左侧是变量(左),而非常量、字面量或表达式结果。 2. **检查是否误用运算符** - 比较操作需用 `==`,赋操作需用 `=`。 3. **避免对数组名直接** - 若需操作数组内容,改用下标或指针: ```c arr[0] = 1; // 正确:修改数组元素 int* ptr = arr; // 正确:通过指针操作 ``` 4. **检查函数返回的使用** - 函数返回是临,不可直接修改: ```c int x = getValue(); // 正确:将返回赋给变量 x x = 100; // 正确:修改的是变量 x ``` --- ### **总结** 此错误的核心原因是**试图对非左(不可修改的表达式)进行赋**。常见于以下情况: - 操作常量、字面量、表达式结果或函数返回- 语法错误(如运算符混淆、数组名误用)。 通过检查赋目标是否合法,并修正语法即可解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值