refactor: 用 Value::get/set 简化属性访问,消除直接 borrow/borrow_mut 调用

- Value::set 签名改为接受 &str 并返回 RuntimeError,与 evaluator 对齐
- eval_get/eval_set/eval_index_get/eval_index_set 中统一使用 get/set
- 去掉 eval_index_get 和 eval_index_set 中不再使用的 map 绑定

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
0264408
2026-06-17 15:05:59 +08:00
parent bc74b5ee91
commit 9428e270af
2 changed files with 35 additions and 15 deletions
+13 -15
View File
@@ -90,9 +90,9 @@ impl super::Interpreter {
fn eval_get(&mut self, object: Expr, name: String) -> Result<Value, RuntimeError> {
let obj = self.evaluate(object)?;
match obj {
Value::Object(map) => {
match map.borrow().get(&name) {
Some(val) => Ok(val.clone()),
Value::Object(_) => {
match obj.get(&name) {
Some(val) => Ok(val),
None => Err(RuntimeError::RuntimeError {
message: format!("Undefined property '{}'", name),
token: None,
@@ -215,19 +215,18 @@ impl super::Interpreter {
let obj = self.evaluate(object)?;
let rhs = self.evaluate(value)?;
match obj {
Value::Object(map) => {
Value::Object(_) => {
let val = match op {
AssignOp::Equal => rhs,
_ => {
let map_borrow = map.borrow();
let current = map_borrow.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
let current = obj.get(&name).ok_or_else(|| RuntimeError::RuntimeError {
message: format!("Property '{}' does not exist", name),
token: None,
})?;
self.apply_assign_op(current.clone(), rhs, op)?
self.apply_assign_op(current, rhs, op)?
}
};
map.borrow_mut().insert(name, val.clone());
obj.set(&name, val.clone())?;
Ok(val)
}
_ => Err(RuntimeError::RuntimeError {
@@ -241,7 +240,7 @@ impl super::Interpreter {
let target = self.evaluate(array)?;
let idx_val = self.evaluate(index)?;
// Object index access: obj["key"]
if let Value::Object(map) = &target {
if let Value::Object(_) = &target {
let key = match &idx_val {
Value::String(s) => s.clone(),
_ => return Err(RuntimeError::RuntimeError {
@@ -249,7 +248,7 @@ impl super::Interpreter {
token: None,
}),
};
return map.borrow().get(&key).cloned().ok_or_else(|| RuntimeError::RuntimeError {
return target.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
message: format!("Undefined property '{}'", key),
token: None,
});
@@ -282,7 +281,7 @@ impl super::Interpreter {
let idx_val = self.evaluate(index)?;
let rhs = self.evaluate(value)?;
// Object index assignment: obj["key"] = value
if let Value::Object(map) = &target {
if let Value::Object(_) = &target {
let key = match &idx_val {
Value::String(s) => s.clone(),
_ => return Err(RuntimeError::RuntimeError {
@@ -293,15 +292,14 @@ impl super::Interpreter {
let val = match op {
AssignOp::Equal => rhs,
_ => {
let map_borrow = map.borrow();
let current = map_borrow.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
let current = target.get(&key).ok_or_else(|| RuntimeError::RuntimeError {
message: format!("Property '{}' does not exist", key),
token: None,
})?;
self.apply_assign_op(current.clone(), rhs, op)?
self.apply_assign_op(current, rhs, op)?
}
};
map.borrow_mut().insert(key, val.clone());
target.set(&key, val.clone())?;
return Ok(val);
}
let i = self.as_array_index(&idx_val)?;
+22
View File
@@ -33,6 +33,28 @@ pub enum Signal {
Continue, // continue 信号
}
impl Value {
pub fn get(&self, key: &str) -> Option<Value> {
match self {
Value::Object(obj) => obj.borrow().get(key).cloned(),
_ => None,
}
}
pub fn set(&self, key: &str, val: Value) -> Result<(), crate::error::RuntimeError> {
match self {
Value::Object(obj) => {
obj.borrow_mut().insert(key.to_string(), val);
Ok(())
},
_ => Err(crate::error::RuntimeError::RuntimeError {
message: "Only objects have properties".to_string(),
token: None,
}),
}
}
}
impl std::fmt::Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {