标签: mutability

Swift:同时将元组解包为可变和不可变变量

我有一个 Swift 函数,它返回两个值的元组。第一个值通常(但并非总是)用作调用者中一段可变状态的“更新”版本(我知道我也可以使用inout它而不是元组,但这使得它更烦人保留旧状态的同时保留新状态)。第二个值是函数生成的通常不可变的返回值,其无意覆盖任何现有的可变状态。

从概念上讲,用法如下:

var state = // initialize
(state, retval1) = process(state)
(state, retval2) = process(state)
(state, retval3) = process(state)
Run Code Online (Sandbox Code Playgroud)

显然,这里的问题是retval1retval2、 和retval3从未被声明,编译器会生气。

state必须是 avar并且不能重新声明,所以我不能写

let (state, retval) = process(state)
Run Code Online (Sandbox Code Playgroud)

但是,retval永远不会被修改,并且应该let作为最佳实践和良好编码风格的问题来声明。

我希望以下语法可能有效,但事实并非如此:

(state, let retval) = process(state)
Run Code Online (Sandbox Code Playgroud)

我应该如何解压/解构这个元组?

coding-style tuples destructuring mutability swift

5
推荐指数
1
解决办法
4682
查看次数

RefCell<X> 和 RefCell<&X> 上的borrow_mut 之间的区别

如果我猜std::rc::Rc,就不可能在 Rust 中通过a创建可变借用,您必须使用CellRefCell。但无论如何我无法理解如何使用它们。例如考虑这个简单的例子

use std::cell::RefCell;

struct X (i32);

impl X {
    fn foo(&mut self) {
        self.0 = 0;
    }
}

fn main () {
    let x = X(5);
    let rcx = RefCell::new(&x);

    let mut mutx: std::cell::RefMut<&X> = rcx.borrow_mut();
    (*mutx).foo();
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

16:5: 16:9 error: cannot borrow immutable local variable `mutx` as mutable
16     mutx.foo();
Run Code Online (Sandbox Code Playgroud)

但是,如果我从行中删除引用(并更新类型mutx):

let rcx = RefCell::new(x);
Run Code Online (Sandbox Code Playgroud)

一切安好。但我不明白为什么,因为RefMut::deref_mut() -> &mut T在第 16 …

reference mutability rust interior-mutability

5
推荐指数
1
解决办法
1003
查看次数

如何在 Rust 中迭代时调用方法

如果这很简单,请道歉。我正在学习 rust 并习惯奇怪的借用系统。通常,您只需更改方法调用的语法即可获得所需的行为,但是,在这种情况下,现在似乎有办法了。

我的代码的简化版本是这样的:EventPumpif from SDL。

struct Example {
    pump: EventPump
}

impl Example {
    fn method(&mut self) {
        for event in pump.poll_iter() {
            self.other_method();
        }
    }

    fn other_method(&self) {

    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
  --> src\game.rs:53:67
   |
30 |             for event in self.pump.poll_iter();
   |                          ---------------------
   |                          | 
   |                          mutable borrow occurs here
   |                          mutable borrow later used here
...
53 |                  self.other_method();
   |                  ^^^^ immutable borrow …
Run Code Online (Sandbox Code Playgroud)

mutability rust borrowing

5
推荐指数
1
解决办法
1213
查看次数

关于引用的可变性和引用所指的值的可变性的一些混淆

我知道 Rust 引用很像 C 指针,并且我一直将 Rust 引用视为 C 指针。经过一些实验和搜索,我很困惑。

\n

我熟悉 C,并且读过What\'s the Difference between Placeing \xe2\x80\x9cmut\xe2\x80\x9d before a variable name and after the \xe2\x80\x9c:\xe2\ x80\x9d?,给出下表:

\n
\n
// Rust          C/C++\n    a: &T     == const T* const a; // can\'t mutate either\nmut a: &T     == const T* a;       // can\'t mutate what is pointed to\n    a: &mut T == T* const a;       // can\'t mutate pointer\nmut a: &mut T == T* a;             // can mutate both\n
Run Code Online (Sandbox Code Playgroud)\n
\n …

reference mutability rust

5
推荐指数
1
解决办法
763
查看次数

如何访问嵌套循环内的可变迭代

我时不时地会遇到在循环内借用(或不借用)可变变量的相同问题,最后我坐下来编译了一个最小的示例。因此,代码有点愚蠢,但这是我能想到的最短版本,突出了问题:

\n
struct Association {\n    used: bool,\n    key: usize,\n    value: String,\n}\n\nimpl Association {\n    fn new(key: usize, value: &str) -> Self {\n        Association{used: false, key: key, value: value.to_string()}\n    }\n}\n\nfn find_unused<\'a>(data: &\'a mut Vec<Association>) -> Option<&\'a String> {\n    for k in 0.. {\n        for a in data {\n            if a.key == k && !a.used {\n                a.used = true;\n                return Some(&a.value);\n            }\n        }\n    }\n    None\n}\n\nfn main() {\n    let mut assoc = vec![\n        Association::new(7, "Hello"),\n        Association::new(9, "World")\n    ];\n\n    println!("{}", find_unused(&mut assoc).unwrap());\n    println!("{}", find_unused(&mut assoc).unwrap());\n}\n …
Run Code Online (Sandbox Code Playgroud)

iterator mutability rust borrow-checker

5
推荐指数
1
解决办法
356
查看次数

C#相当于Python的id()?

是否有一个C#等同于Python的id()?如果没有,我如何测试对象是否已更改?例如,在Python中,一个不可变对象:

>>> s = "abc"
>>> id(s)
11172320
>>> s += "d"
>>> id(s)
18632928
Run Code Online (Sandbox Code Playgroud)

一个可变的:

>>> a = [1, 2, 3]
>>> id(a)
11259656
>>> a += [4]
>>> id(a)
11259656
Run Code Online (Sandbox Code Playgroud)

编辑 - 到目前为止,大多数答案都是关于比较函数/运算符,但我对正在比较的值更感兴趣.我最初并不清楚这一点,我接受Object.ReferenceEquals了答案.

c# python mutability

4
推荐指数
2
解决办法
444
查看次数

可变值和不可变值重定义之间有什么区别?

我已经读过F#中的值是不可变的.但是,我也遇到了重新定义值定义的概念,它影响了以前的定义.这与可变值有什么不同?我这不仅仅是作为理论构造,而且还有关于何时使用可变值以及何时重新定义表达式的建议; 或者如果有人能够指出后者不是惯用的f#.

重新定义的基本示例:

let a = 1;;
a;; //1
let a = 2;;
a;; //2
Run Code Online (Sandbox Code Playgroud)

更新1:

添加到下面的答案中,顶级Fsharp交互式中的重新定义仅允许在不同的终端中.以下将在fsi中引发错误:

let a = 1
let a = 2;;

Error: Duplicate definition of value 'a'
Run Code Online (Sandbox Code Playgroud)

另一方面,let绑定允许重新定义.

更新2:实际差异,闭包不能使用可变变量:

let f =
   let mutable a = 1
   let g () = a //error
   0  
f;;
Run Code Online (Sandbox Code Playgroud)

更新3:

虽然我可以使用refs模拟副作用,例如:

let f =
   let  a = ref 1
   let g = a
   a:=2
   let x = !g  + !a
   printfn "x: %i" x //4

f;;
Run Code Online (Sandbox Code Playgroud)

我不太清楚重新定义和使用mutable关键字之间的实际区别,除了使用闭包的区别,例如:

let f  = …
Run Code Online (Sandbox Code Playgroud)

f# functional-programming immutability mutability

4
推荐指数
1
解决办法
564
查看次数

如何轻松地将非mut&[u8]复制到&mut [u8]

我想对&mut [u8]做一些操作.

在我的测试代码中,我有:

#[test]
fn test_swap_bytes() {
    let input: &[u8] = b"abcdef";
    let result: &mut[u8] = ?;
    do_something(result);
    assert_eq!(b"fedcba", result);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如何轻松获得可变的u8切片?我该怎么把问号放在哪里?

copy slice mutability rust

4
推荐指数
2
解决办法
196
查看次数

NSNumber对mutableCopy有积极的反应?

这是一个错误还是这里有一个微妙的教训?

NSNumber *someNumber = @(1);
[someNumber respondsToSelector:@selector(mutableCopy)]; // returns YES (!)
[someNumber respondsToSelector:@selector(mutableCopyWithZone:)]; // returns NO
Run Code Online (Sandbox Code Playgroud)

Apple LLVM 7.1(iOS SDK 9.3)

objective-c nsnumber mutability

4
推荐指数
1
解决办法
91
查看次数

ValueTuple结构只能作为变量变化吗?

我玩弄了ValueTuple结构并试图实现一个不可变的复合键.密钥由值类型组成.

我尝试用一​​些单元测试打破以下实现,到目前为止还没有成功.我错过了什么吗?

这也只是出于好奇,我想ValueTuple在.NET 4.7发布之前得到s和它的局限性.

到目前为止,我对a的理解ValueTuple是它只作为变量而不是作为字段或属性变化.不知道"可变"在这里意味着什么.更改ValueTuple实例实际上是否创建了一个新的ValueTuple(就像它的常识一样,字符串是"不可变的"但实际上是引用类型)?

这个答案

System.ValueTuple不仅是一个struct,它是一个可变的,并且在使用它们时必须要小心.想想当一个班级System.ValueTuple作为一个领域时会发生什么.

在这里我的实施和测试

public interface IHaveCompositeKey
{
    (Guid id, string name) Key { get; }
}

public class ImmutableKey : IHaveCompositeKey
{
    public (Guid id, string name) Key { get; }
    public ImmutableKey((Guid id, string name) key) => Key = key;
    public override int GetHashCode() => Key.GetHashCode();
    public override bool Equals(object obj)
    { …
Run Code Online (Sandbox Code Playgroud)

c# immutability mutability valuetuple

4
推荐指数
1
解决办法
802
查看次数