-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[第五章] 诸多名词概念不应强行关联 #77
Comments
@kvinwang 感谢反馈。这是第三次印刷要修订的内容。 在不同的语言概念里,值语义应该有不同的理解。其实放到Rust语言里,Copy就是判断Rust中值语义类型的一种依据。 |
我见过的有官方明确定义或解释值语义的语言有C++/Swift/Nim,他们对值语义的定义都是一致的。 |
@kvinwang 我已明白你意思。上面说的那些对应关系后面会修正的更加精准。 |
@kvinwang 审校下。 修正内容:
|
@mzji 也帮忙审校下上面的修正 |
Rust 里,除了引用以外并没有真正意义上的引用类型吧…… |
值语义&引用语义的理解值语义和引用语义是描述一个类型在“赋值”或传参时的行为是否复制了该类型描述的“值”。 // 基本类型是值语义
int a = 1;
int b;
b = a; // 将int代表的值1从a拷贝到了b里面。
// 指针也是值语义,因为字面意义上指针的值就是地址
const char* a = "hi";
const char* b;
b = a; // 将"地址"从a拷贝到了b里面。
// 重新定义的指针, 引用语义
typedef const char* str; // 现在str代表字符串了,意义上不在是“针”
str a = "hi";
str b;
b = a; // str描述的值-字符串,没有被拷贝, 因此是引用语义。 内存表示上完全相同的 |
浅拷贝&深拷贝的理解浅拷贝和深拷贝,这个深浅是相对的,只能有框架性的定义,不能从技术上对所有类型的拷贝细节进行统一规定。每个类型都可以定义自己何为深、何为浅。正如我们小学课文《小马过河》所学,松鼠会觉得河水达到10CM就是深,但对于老牛来讲100CM也不算深。 以Python的list举例说明:
实际上,在Python的标准库中,对深拷贝和浅拷贝进行了框架性规定。区别就是浅拷贝只在该类型上执行一次 |
按位复制的理解很简单,按位复制就是据需要复制数据的大小按每bit原样复制。与是否在栈上无关。 #[derive(Copy, Clone)]
struct A(i8, i32);
fn main() {
let a = A(1, 2);
let b = a; // 按位复制
let c = A(a.0, a.1); // 逐成员复制,非按位复制
// 注意二者的区别:按位复制会连padding部分一起复制。
// 复制后,b和a完全相同,包括padding部分。c和a的padding部分不一定相同。
} |
@kvinwang 辛苦了。 我再修正一下描述。 |
这么说的话,Rust 里的引用类型除了引用外,主要就是那些实现了 deref/deref_mut 的类型吧 |
@mzji 回头我整理个单独贴,其实这个话题已经很清晰了,我明天整理出结果,重开个issues。 |
考虑到这一点, deref / deref_mut 不应被实现为值语义。 |
应该当然是应该,字面上就能看出来应该实现为引用语义。还是那句话,should不能被当做must,不能把should的东西当成判别标准,否则就变成错误了,尤其是写到书上就更需要严谨了。 Edit: |
合并到这个issues讨论: 对书中值语义、引用语义、栈拷贝、按位复制等概念的澄清 |
那只好再精确一点,引用和智能指针 |
万事总能找出特例的。只要没有太大的错误,读者方便理解,暂时就不想再深抠下去了。书是没办法讲那么细致的。 |
第五章里面将“按位复制”、“栈复制”、“浅复制/深复制”、“值语义/引用语义”等概念强行关联起来,实际上这些关联关系并不成立。
例如:
值类型判断标准和赋值语句时的复制语义有关,和是否存储在栈上无关。
问题同上( 数据也可以放在栈上,指针也可以放到堆上)[1]
值语义的复制不一定要按位复制。
问题同[1]
这里进一步错误地引入浅复制和深复制的概念。实际上,深/浅复制,和是否在栈上或是否是按位复制都没有关系。浅复制的数据完全可以在堆上,也可以不按位来复制, 深复制的数据也完全可以全部存在于栈上。
Copy语义和值语义是不同的概念。Rust中非Copy的但满足值语义的类型很常见。
实际上, 这些概念都有自己的定义,分开理解就好,不应该强行关联。
The text was updated successfully, but these errors were encountered: