So, I understand that arrays in JavaScript are mutable.
意味着如果我创建数组a和数组b = a,那么如果我修改数组a,修改在数组中也可见b。
但是,在以下情况下,我不明白为什么b会丢失对array的“引用” a。
var a = [1,2,3];
var b = a;
console.log('a =', a);
console.log('b =', b);
a[0] = 4;
console.log('a =', a);
console.log('b =', b);
a = [5,5];
console.log('a =', a);
console.log('b =', b);Run Code Online (Sandbox Code Playgroud)
该锈书大约有多个读者和多个可变对象引用的数据竞争情况,可能会导致问题进行会谈。
例如,这段代码:
fn main() {
let mut x = 1;
let r1 = &mut x;
*r1 = 2;
let r2 = &mut x;
*r2 = 3;
println!("{}", r1);
println!("{}", r2);
}
Run Code Online (Sandbox Code Playgroud)
将被 Rust 编译器拒绝,因为r1和r2作用域交织在一起。
但是这里有什么问题呢?我的意思是,这只是一个线程,没有“同时读取和写入”,因此所有这些语句都应严格按顺序执行并给出确定性的可重现结果。
我仍然很难理解为什么&mut self需要修改我的结构所拥有的对象的内部状态。我明白为什么我必须使用至少&self,因为我不想消费self,结束它的存在。我也明白为什么我必须使用&mut self如果我修改结构的字段,但我不这样做。
我有以下结构和实现:
\nstruct Writer {\n obj: json::JsonValue\n}\n\nimpl<\'b> Writer {\n fn from(obj: json::JsonValue) -> Self {\n Self {\n obj\n }\n }\n\n fn put(&mut self, field_name: &str, value: bool) {\n self.obj.insert(field_name, value);\n // ^^^- not modifying this, but a field inside "obj"\n }\n\n fn release_ownership(self) -> json::JsonValue {\n self.obj\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n用法:
\nwriter.put(field_name, true);\nRun Code Online (Sandbox Code Playgroud)\n使用&self而不是&mut self我会得到一个编译器错误:
`^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so …Run Code Online (Sandbox Code Playgroud) 这是我的代码,它可以编译
trait AppendBar {
fn append_bar(self) -> Self;
}
impl AppendBar for Vec<String> {
fn append_bar(mut self) -> Self {
self.push("Bar".to_string());
self
}
Run Code Online (Sandbox Code Playgroud)
虽然它获取了所有权,但是为什么它可以在实现过程中改变 self 呢?
let mut a = Box::new("123".to_string());
let b = Box::new( &mut a);
b.push('4');
assert_eq!( "1234", b.as_str());
// lets see the types:
// let x001: Box<&mut Box<String>> = b;
// let x001:&mut Box<String> = *b;
// let x001:Box<String> = **b;
// let x001:String = ***b;
// let x001:str = ****b;
let c = Box::new("456".to_string());
**b = c;
b.push('9');
(*b).push('9');
(**b).push('9');
(***b).push('9');
// (****b).push('9'); // no method named `push` found for type `str` in the current scope
// c.push( 'a'); // cannot mutate …Run Code Online (Sandbox Code Playgroud) 如果我想调用这样的方法:
List f(List l){
l.add(new Object());
return l;
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,除非我调用该方法,它实际上修改了它的参数,反正在那周围?
// suppose l is instantiated at this point
log.info(l.count());// prints 0
f(l);
log.info(l.count());// prints 1
Run Code Online (Sandbox Code Playgroud)
无论如何在java中声明f以保持l不变?
我知道我可以在l上执行深度克隆并传递它,但是在l非常大的情况下,此操作很昂贵.
在第一种情况下,我按值传递一个映射: package main
import (
"fmt"
"time"
)
func timeMap(z map[string]interface{}) {
z["updated_at"] = time.Now()
}
func main() {
foo := map[string]interface{}{
"Matt": 42,
}
timeMap(foo)
fmt.Println(foo)
}
Run Code Online (Sandbox Code Playgroud)
输出是一个静音地图:
map[updated_at:2009-11-10 23:00:00 +0000 UTC Matt:42]
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,代码几乎相同,但通过引用传递:
package main
import (
"fmt"
"time"
)
func timeMap(z *map[string]interface{}) {
(*z)["updated_at"] = time.Now()
}
func main() {
foo := map[string]interface{}{
"Matt": 42,
}
timeMap(&foo)
fmt.Println(foo)
}
Run Code Online (Sandbox Code Playgroud)
显然,结果不同:
map[Matt:42 updated_at:2009-11-10 23:00:00 +0000 UTC]
Run Code Online (Sandbox Code Playgroud)
我的期望如下:
我有以下片段的Rust:
pub fn scope(&mut self) -> &mut HashMap<String, Type> {
let idx = self.vars.len() - 1;
&mut self.vars[idx]
}
Run Code Online (Sandbox Code Playgroud)
我已经意识到我有一些上下文,我想在函数的非可变版本中使用此函数,例如:
pub fn scope(&self) -> &HashMap<String, Type> {
let idx = self.vars.len() - 1;
&self.vars[idx]
}
Run Code Online (Sandbox Code Playgroud)
mut两个功能之间只删除了3 秒.我可以以某种方式将这些变成一个函数,根据可变性来推导我返回的引用的可变性self吗?是否有一些我可以使用或类似的特征?
我正在学习子结构类型系统,Rust是一个很好的例子。
数组在Rust中是可变的,可以访问多次,而不是只能访问一次。“值读取”,“参考读取”和“可变参考读取”之间有什么区别?我编写了如下程序,但出现了一些错误。
fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
println!("first element of the array: {}", xs[1]);
println!("first element of the array: {}", &xs[1]);
println!("first element of the array: {}", &mut xs[1]);
}
Run Code Online (Sandbox Code Playgroud)
这是错误消息:
fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
println!("first element of the array: {}", xs[1]);
println!("first element of the array: {}", &xs[1]);
println!("first element of the array: {}", &mut xs[1]);
}
Run Code Online (Sandbox Code Playgroud) 我想用另一个元素替换数组中的特定元素,如下所示:
let replace = ["123","87","123","765","som","123","op","123"].map {$0 == "123" ? $0 = "replace" : $0}
Run Code Online (Sandbox Code Playgroud)
但我不能这样做,因为编译器会抛出我的错误:
error: cannot assign to value: '$0' is immutable
Run Code Online (Sandbox Code Playgroud)
那么,这可能会改变0美元变得可变吗?
我这样说明了一下:
fn main() {
let mut opt1 = Some(1);
// compiler complains that opt2 doesn't have to be mutable
let mut opt2 = Some(1);
fn take_inner(mut opt: Option<u8>) {
opt.take();
};
opt1.take();
take_inner(opt2);
println!("opt1 {:?}", opt1); // prints "opt1 None"
println!("opt2 {:?}", opt2); // prints "opt2 Some(1)"
}
Run Code Online (Sandbox Code Playgroud)
为什么opt.take()函数内的调用与外部调用(相对于main函数的作用域)有不同的效果?
假设我有这个代码:
let mut s = "hi".to_string();
let c = || s.push_str(" yo");
c();
Run Code Online (Sandbox Code Playgroud)
它不会编译并生成此错误:
error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable
--> src\test.rs:120:9
|
119 | let c = || s.push_str(" yo");
| - - calling `c` requires mutable binding due to mutable borrow of `s`
| |
| help: consider changing this to be mutable: `mut c`
120 | c();
| ^ cannot borrow as mutable
For more information about this error, try …Run Code Online (Sandbox Code Playgroud)