我是 python 新手,刚刚学习不可变和可变对象(由于我在 MATLAB 和 C# 方面的编码经验有限,我以前从未遇到过这种情况)。
我想知道为什么,如果 python 中的字典是可变的,那么编辑第二个字典中包含的字典不会更改第二个字典吗?
这是一个示例,其中将字典(蝙蝠侠)添加到超级英雄名称字典(super_hero_names)中。当蝙蝠侠后来被更改时,它不会反映在超级英雄名称字典中。如果字典像字符串一样不可变,这对我来说是有意义的,但它们是可变的,那么为什么会发生这种情况呢?
super_hero_names = {
'Superman' : 'Clark Kent',
'Spiderman' : 'Peter Parker'
}
batman = {'Batman' : 'Bruce'}
super_hero_names.update(batman)
batman['Batman'] = 'Bruce Wayne' # (edited)
print(super_hero_names)
# Output: {'Superman': 'Clark Kent', 'Spiderman': 'Peter Parker', 'Batman': 'Bruce'}
Run Code Online (Sandbox Code Playgroud) 在Python中,我们可以使用@property装饰器来管理对属性的访问。例如,如果我们定义类:
class C:
def __init__(self,value):
self._x = value
@property
def x(self):
"""I'm the 'x' property."""
return self._x
Run Code Online (Sandbox Code Playgroud)
我们可以获取 x 的值,但不能更改它:
c = C(1)
#c.x = 4 # <= this would raise an AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
但是,如果属性是可变类型(例如列表),我们可以为属性的位置设置不同的值:
c = C([0,0])
c.x[0] = 1 # <= this works
Run Code Online (Sandbox Code Playgroud)
有办法预防吗?如果 x 是一个列表,我希望能够仅使用 C 类的方法来更改 x 位置的值。
我是 Rust 新手,我正在尝试将计算工作分配给线程。
我有字符串向量,我想为每个字符串创建一个线程来完成他的工作。有简单的代码:
use std::thread;
fn child_job(s: &mut String) {
*s = s.to_uppercase();
}
fn main() {
// initialize
let mut thread_handles = vec![];
let mut strings = vec![
"hello".to_string(),
"world".to_string(),
"testing".to_string(),
"good enough".to_string(),
];
// create threads
for s in &mut strings {
thread_handles.push(thread::spawn(|| child_job(s)));
}
// wait for threads
for handle in thread_handles {
handle.join().unwrap();
}
// print result
for s in strings {
println!("{}", s);
}
}
Run Code Online (Sandbox Code Playgroud)
我在编译时遇到错误:
error[E0597]: `strings` does not live long enough
--> …Run Code Online (Sandbox Code Playgroud) 看看这个简单的例子.我不太明白为什么o1打印两次"Hello Alex".我认为因为默认的self.a总是重置为空列表.有人可以向我解释一下这里的理由是什么?非常感谢.
class A(object):
def __init__(self, a=[]):
self.a = a
o = A()
o.a.append('Hello')
o.a.append('Alex')
print ' '.join(o.a)
# >> prints Hello Alex
o1 = A()
o1.a.append('Hello')
o1.a.append('Alex')
print ' '.join(o1.a)
# >> prints Hello Alex Hello Alex
Run Code Online (Sandbox Code Playgroud) 我有一个问题,但要得到答案,首先要接受以下事实:在某些情况下,可以修改Java字符串.
这已在Artima文章中标明:"hi there".equals("cheers!")== true
链接:http://www.artima.com/weblogs/viewpost.jsp? thread = 4864
它仍然可以在Java 1.6中很好地运行,它肯定会以某种方式反对流行的信念,即重复"Java字符串总是不可变的".
所以我的问题很简单:可以像这样修改字符串,是否有任何JVM安全设置可以打开以防止这种情况?
在C++中,您现在可以拥有mutable成员.这为语言添加了一层"逻辑const".这些如何与只读数据相关 - 是否有mutable成员阻止将const类放入一个.rodata节?
class Foo {
mutable int bar;
public:
Foo(): bar(0) {}
void set(int x) const { bar = x; }
};
// Can this be in a read-only section?
const Foo foo;
int main(void)
{
// Is this well-defined?
foo.set(5);
}
Run Code Online (Sandbox Code Playgroud) 我知道'mutable'和'immutable'是应该用来描述对象改变面向对象语言(如Java和Objective C)中的值的能力的术语.但是,我想提出它,因为它与我有关关于原始数据的问题.我知道当我更改包含不可变对象的变量的值时,我实际上是在创建一个新对象.但是,我想知道C中的原语数据是否与不可变对象类似.我的意思是,当我更改保存原始数据的变量的值时,会创建一个新数据并由变量引用.或者现有的基元实际上是否突变/修改了存储的数据值?
编辑#1:
问题#1:我想澄清一些误解(无论是我还是其他人),因为当我说"当我改变保存不可变对象的变量的值时,我实际创建了一个新对象." 当我这样说时,我并不是要将变量赋给现有对象.例如:
// Example 1: I did not mean this
-------------------------
String x = "Hello World";
String y = x;
-------------------------
// Example 2: What I meant is this
-------------------------
String x = "Hello World";
//This will print out "Hello World"
System.out.println(x);
x = "Goodbye World";
//This will print out "Goodbye World"
System.out.println(x);
-------------------------
Run Code Online (Sandbox Code Playgroud)
当然,如示例1所示,将变量y赋给变量x,这是你们提出的情况,只引用变量y到x引用的对象.当然,在这种情况下,没有新的对象; 只有同一个对象"Hello World"被2个变量引用.
我的意思是当例子2中x ="Goodbye World"时,变量x引用一个新的String对象,其值为"Goodbye World",而不是x初始化的第一个String对象"Hello World".String是Java中的Immutable对象.更改String变量值的唯一方法是让变量引用现有对象或新String对象.如果没有现有对象("Goodbye World"字符串对象未在任何地方创建),则上面的代码只是创建了一个新的String对象并引用了它.我对吗?如果没有,请纠正我.
问题#2:我想总结答案,尤其是Ulfalizer的答案:
1)实际上有两种形式可以存在变量:
a)"存储器地址" - 对于基本类型数据,C语言中的变量以及Java和目标C就是这种情况.例如:int x = 1.这里的变量x是一个实际的内存地址本身,它的类型为整数,并用值1初始化. …
我想实现Fibonacci系列以及缓存已经计算的结果.我不确定这种方法在Rust中是否可行,但它是我提出的最好的方法.这是代码:
use std::collections::HashMap;
pub fn fib_hash(n: u32) -> u64 {
let mut map: HashMap<u32, u64> = HashMap::new();
// This is the engine which recurses saving each value in the map
fn f(map: &HashMap<u32, u64>, n: u32) -> u64 {
let c = match map.get(&n) {
Some(&number) => number,
_ => 0,
};
if c != 0 {
return c;
}
let m = match n {
1 if n < 1 => 0,
1...2 => 1,
_ => f(&map, n …Run Code Online (Sandbox Code Playgroud) 我正在测试该ImmutableObjectAttribute属性只是为了好奇,看看我是否可以获得一些应用它的好处,或者它是否仅仅用于语义装饰......
指定对象没有能够编辑的子属性.
所以我有这门课:
<ImmutableObject(True)>
Public Class TestClass
<ImmutableObject(True)>
Public sb As StringBuilder
Public Sub New()
sb = New StringBuilder
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
我已经使用此代码进行了测试:
Dim obj As New TestClass
obj.sb.Append("Hello")
obj.sb.Append(" ")
obj.sb.Append("World")
MsgBox(obj.sb.ToString)
Run Code Online (Sandbox Code Playgroud)
然后,我会应用后ImmutableObject的可变对象的属性,我希望看到某种编译器警告的,某种运行时异常的,或者只是从的内部串收到意想不到的价值StringBuilder,但没有那事情发生了,一切似乎都正常.
这让我觉得一个问题的答案显而易见,但我需要问一下:
ImmutableObject属性只是一个装饰性的属性?为什么存在这个属性呢?我找不到任何标记具有此属性的类的beneffit它不能确保成员实际上是不可变的,或者至少是.Net理解为不可变的(你知道,就像String在.Net中不是真正不可变的).
我试过了:
let mut vec = [1,2,3];
for mut x in &vec { *x=3; }
for mut &x in &vec { x=3; }
for mut *x in &vec { x=3; }
for mut x in mut &vec { *x=3; }
for mut x in &(mut vec) { *x=3; }
Run Code Online (Sandbox Code Playgroud)
这些都不起作用; 我该怎么办?
mutable ×10
python ×3
rust ×3
immutability ×2
java ×2
.net ×1
arguments ×1
borrowing ×1
c ×1
c++ ×1
const ×1
dictionary ×1
for-loop ×1
objective-c ×1
primitive ×1
properties ×1
python-3.x ×1
setter ×1
string ×1
vb.net ×1
vector ×1