我最近问某人为什么他更喜欢在IList上返回一个强类型数组.我一直认为,当面对一个具有长寿命的项目时,针对接口的编程是最灵活和最好的方式.所以当他回答时,我很奇怪:
我们通常更喜欢不可变类型而不是可变类型.数组是不可变的.IList不是.
我不完全确定我理解这句话.任何人都可以帮忙澄清一下吗?
感谢您提供的任何帮助.
你好,这里有jQuery的新菜鸟,我想知道jQuery对象是不可变的.例如:
var obj1 = $("<tag></tag>");
var obj2 = obj1.append("something");
Run Code Online (Sandbox Code Playgroud)
obj1和obj2是否相同意味着obj2会引用obj1?
更新:
上面的例子有点划伤我想知道的表面,一个更准确的问题是:如果我从jQuery api链接函数将返回相同的对象或新的(如Java中的字符串的情况)?
所以我正在使用Racket Scheme自学编程功能,到目前为止我都喜欢它.作为我自己的练习,我一直在尝试以纯粹的功能方式实现一些简单的任务.我知道不变性是功能风格的重要组成部分,但我想知道是否有任何时候它是可以的.
我想到了一种函数在与filter一起使用时从字符串列表中删除非唯一字符串的有趣方式,如下所示:
(define (make-uniquer)
(let ([uniques '()])
(lambda (x)
(if (not (member x uniques))
(set! uniques (cons x uniques))
#f))))
(define (uniquify x)
(let ([uniquer (make-uniquer)])
(filter uniquer x)))
Run Code Online (Sandbox Code Playgroud)
如您所见,make-uniquer在一个字符串列表上返回一个闭包,以便与唯一性进行比较,这样它就可以作为过滤器的简单谓词.但我破坏性地更新了封闭式清单.这是不好的形式,还是以这种方式改变本地封闭变量?
lisp scheme functional-programming mutability purely-functional
显然,const除非某些东西是可变的,否则使用它是一种好习惯,但你走了多远?如果我有一个字符串数组,我的函数签名是否应该包括这个?
char const * const * const my_strings
Run Code Online (Sandbox Code Playgroud)
我不会被修改它无论如何,所以这是一个常数指针恒定指针的恒定字符阵列的所述第一元件的阵列的第一个元素.这是一个满口,代码几乎是不可读的.这一切都是简单的数据结构argv.
我觉得const应该是默认的,并且应该有一个mutable关键字.
你一般只是其中一个const吗?那么,如果您仍然可以通过解除引用或多或少来轻松地改变它,那又有什么意义呢?
我正在尝试计算合法的国际象棋动作,并且在满足借阅检查器方面遇到了问题.我有一个Chess实现这些方法的结构(替换为非重要代码...):
// internal iterator over (possibly not legal) moves
fn get_moves<F>(&self, func: F)
where
F: Fn(/* ... */),
{
func(/* ... */); // move 1
func(/* ... */); // move 2
func(/* ... */); // etc...
}
fn is_legal_move(&mut self) -> bool {
// notice this takes a mutable self. For performance
// reasons, the move is made, legality is checked, then I
// undo the move, so it must be mutable to be able to …Run Code Online (Sandbox Code Playgroud) let mut result = String::with_capacity(1000);
result.push_str("things... ");
result.push_str("stuff... ");
result.truncate((result.len() - 4));
Run Code Online (Sandbox Code Playgroud)
但是,这是一个编译错误.与借用检查器有关,可能还有可变性.
error[E0502]: cannot borrow `result` as immutable because it is also borrowed as mutable
--> <anon>:7:22
|
7 | result.truncate((result.len() - 4));
| ------ ^^^^^^ - mutable borrow ends here
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
Run Code Online (Sandbox Code Playgroud)
然而,如果我稍微改变它,我可以这样做:
let newlen = result.len() - 4;
result.truncate(newlen);
Run Code Online (Sandbox Code Playgroud)
为什么?有没有办法改变它,所以它可以写在一行?(PS这是在Rust 1.0上)
我有一个包含两个字段的结构,我想使用另一个字段(不可变借用)修改一个字段(可变借用),但是我从借用检查器得到一个错误.
例如,以下代码:
struct Struct {
field1: Vec<i32>,
field2: Vec<i32>,
}
fn main() {
let mut strct = Struct {
field1: vec![1, 2, 3],
field2: vec![2, 3, 4],
};
strct.field1.retain(|v| !strct.field2.contains(v));
println!("{:?}", strct.field1);
}
Run Code Online (Sandbox Code Playgroud)
给出以下错误:
error[E0502]: cannot borrow `strct.field1` as mutable because it is also borrowed as immutable
--> src/main.rs:12:5
|
12 | strct.field1.retain(|v| !strct.field2.contains(v));
| ^^^^^^^^^^^^^------^---^^-----^^^^^^^^^^^^^^^^^^^^
| | | | |
| | | | first borrow occurs due to use of `strct` in closure
| | | immutable borrow …Run Code Online (Sandbox Code Playgroud) 我有以下代码(playground):
struct A {
pub vec: Vec<u64>,
}
impl A {
fn perform_for_all<F: Fn(&mut u64)>(&mut self, f: F) {
for mut i in &mut self.vec {
f(i);
}
}
}
fn main() {
let mut a = A {
vec: vec![1, 3, 44, 2, 4, 5, 6],
};
let mut done = false;
a.perform_for_all(|v| {
println!("value: {:?}", v);
done = true;
});
if !done {
a.perform_for_all(|v| {
println!("value {:?}", v);
});
}
}
Run Code Online (Sandbox Code Playgroud)
发生以下错误:
error[E0594]: cannot assign to …Run Code Online (Sandbox Code Playgroud) 在Rust Book,Variables和Mutability的第3章中,我们对这个主题进行了几次迭代,以演示Rust中变量的默认,不可变行为:
fn main() {
let x = 5;
println!("The value of x is {}", x);
x = 6;
println!("The value of x is {}", x);
}
Run Code Online (Sandbox Code Playgroud)
哪个输出:
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
3 | println!("The value of x is {}", x);
4 | x = …Run Code Online (Sandbox Code Playgroud) 我正在通过锻炼来学习Rust。在此文件中,目标是像在电子表格中一样更新单元格:当值更改时,必须重新计算从该单元格派生的所有单元格。在这里,这些被称为该单元的父母。
更新单元格的值证明没有问题,但是更新父母会使我与借贷检查器发生冲突。从a检索单元格HashMap并更新值后,我不再需要可变的引用-因此我尝试将其包装在不可变的引用中。这样,我只需要找到一次即可。
但是似乎Rust的数字是因为我最初从借来的书中得到了我一成不变的参考&mut self,所以它仍然必须与之绑定。显然,这使我无法再次使用self。
use std::collections::HashMap;
use std::vec::Vec;
struct Cell {
value: i32,
parents: Vec<u32>,
}
pub struct Sheet {
table: HashMap<u32, Cell>,
}
impl Sheet {
pub fn set_value(&mut self, identifier: u32, new_value: i32) {
let mut updated_cell: Option<&Cell> = None;
if let Some(cell) = self.table.get_mut(&identifier) {
let Cell { value, .. } = cell;
*value = new_value;
updated_cell = Some(cell);
}
if let Some(cell) = updated_cell {
recalculate(self, &cell.parents);
}
}
} …Run Code Online (Sandbox Code Playgroud)