作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道两者之间有什么区别:
"some string".to_string()
"some string".into_string()
consume
是什么意思一个值 ?这两个特质有什么区别?
into_string
对于
String
.如您所见,它只返回自身,因此没有进行分配。
最佳答案
移动语义
What does it mean to
consume
a value?
Vec
的
Ascii
字符:
asciis
.
fn main() {
let asciis = vec!['h'.to_ascii(), 'i'.to_ascii()];
println!("{}", asciis);
}
Vec
是一个包含三个字段的结构体:
Vec
的长度. Vec
容量. Vec
管理的数据的指针. Vec
的内存布局它管理的数据可能看起来像这样。
Stack: asciis Heap:
+----------+ +----------+
0xF0 | data | ----> 0xA0 | 'h' |
+----------+ +----------+
0xF4 | length | 0xA1 | 'i' |
+----------+ +----------+
0xF8 | capacity |
+----------+
Vec
超出范围,它释放它管理的内存。释放的内存对我们来说是垃圾。访问释放的内存是错误的。这将类似于以下内容。
Vec
消失了,堆上的内存已被释放。
Heap:
+----------+
0xA0 | GARBAGE |
+----------+
0xA1 | GARBAGE |
+----------+
asciis
.
fn main() {
let asciis = vec!['h'.to_ascii(), 'i'.to_ascii()];
{
let an_attempted_copy = asciis;
}
println!("{}", asciis);
}
an_attempted_copy
是
asciis
的副本.在我们复制之后,我们的内存可能看起来像下面这样。
Stack: asciis Heap: Stack: an_attempted_copy
+----------+ +----------+ +----------+
0xF0 | data | ----> 0xA0 | 'h' | <---- 0xE0 | data |
+----------+ +----------+ +----------+
0xF4 | length | 0xA1 | 'i' | | length |
+----------+ +----------+ +----------+
0xF8 | capacity | | capacity |
+----------+ +----------+
println!
asciis
,
an_attempted_copy
超出范围!和之前一样,我们
Vec
指向的数据被释放。
Stack: asciis Heap:
+----------+ +----------+
0xF0 | data | ----> 0xA0 | GARBAGE |
+----------+ +----------+
0xF4 | length | 0xA1 | GARBAGE |
+----------+ +----------+
0xF8 | capacity |
+----------+
asciis
指向释放的内存!这是个坏消息,因为我们即将
println!
asciis
.
asciis
进入 an_attempted_copy
,我们可以复制asciis
指向的数据到一块新分配的内存中。其他语言如 C++ 这样做。 asciis
,我们可以移动它!这就是 rust 的作用。 an_attempted_copy
将获得以前由
asciis
指向的数据的所有权.
asciis
失去所有权,我们不能再使用它。让我们重命名
an_attempted_copy
为了清楚起见。
fn main() {
let asciis = vec!['h'.to_ascii(), 'i'.to_ascii()];
{
let actually_a_move = asciis;
}
println!("{}", asciis);
}
actually_a_move
后立即绘制我们的内存布局。 .
Stack: asciis Heap: Stack: actually_a_move
+----------+ +----------+ +----------+
0xF0 | GARBAGE | 0xA0 | 'h' | <---- 0xE0 | data |
+----------+ +----------+ +----------+
0xF4 | GARBAGE | 0xA1 | 'i' | | length |
+----------+ +----------+ +----------+
0xF8 | GARBAGE | | capacity |
+----------+ +----------+
asciis
不再拥有内存,所以我们不能使用
asciis
了。这意味着它几乎是垃圾。所以如果我们不能使用
asciis
不再,当我们
println!
会发生什么它?我们得到以下错误。
<anon>:6:24: 6:30 error: use of moved value: `asciis`
<anon>:6 println!("{}", asciis);
^~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
<anon>:6:9: 6:32 note: expansion site
<anon>:4:17: 4:32 note: `asciis` moved here because it has type `collections::vec::Vec<std::ascii::Ascii>`, which is moved by default (use `ref` to override)
<anon>:4 let actually_a_move = asciis;
^~~~~~~~~~~~~~~
error: aborting due to previous error
ascii
,但是
ascii
是一个移动的值;这是错误的。
to_string
对比
into_string
What is the difference between the two traits?
to_string
的类型签名.
fn to_string(&self) -> String;
self
并返回一个新的
String
供我们使用。我还没有讨论引用资料以及它们如何影响运动,但是当我说这里没有进行任何运动时请相信我。
into_string
的类型签名.
fn into_string(self) -> String;
self
.相反,
self
被移动到函数中。
fn main() {
let asciis = vec!['h'.to_ascii(), 'i'.to_ascii()];
let no_moves_here = asciis.to_string();
println!("{}", asciis);
}
Vec
的
Ascii
人物。然后,当我们拨打
asciis.to_string()
,全新
String
已创建并
asciis
从不移动。此代码将按照您的预期构建和运行,打印出
[h, i]
.现在,让我们使用
into_string
.
fn main() {
let asciis = vec!['h'.to_ascii(), 'i'.to_ascii()];
let uh_oh_we_just_moved_asciis = asciis.into_string();
println!("{}", asciis);
}
<anon>:4:24: 4:30 error: use of moved value: `asciis`
<anon>:4 println!("{}", asciis);
^~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
<anon>:4:9: 4:32 note: expansion site
<anon>:3:42: 3:48 note: `asciis` moved here because it has type `collections::vec::Vec<std::ascii::Ascii>`, which is non-copyable (perhaps you meant to use clone()?)
<anon>:3 let uh_oh_we_just_moved_asciis = asciis.into_string();
^~~~~~
error: aborting due to previous error
asciis
正在移入函数
into_string
.就像我们上次尝试使用
asciis
一样在我们移动它之后,rust 编译器将拒绝我们的代码。
关于rust - ToString 和 IntoString 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25316115/
我想知道两者之间有什么区别: "some string".to_string() 和 "some string".into_string() 前者好像来自ToString ,这是很清楚的。 然而,后者
我正在尝试为一些天气数据制作我的 xml 解析器的快速版本: import Cocoa import Foundation let string2: NSString? = "cdefg jajaja
使用 Instruments 时,此方法似乎存在泄漏 (scanCharactersFromSet:intoString:)。我不会释放放入 intoString 中的变量 此方法是否在方法的 int
NSString *markdown = @"This is the *Markdown* syntax."; NSScanner *aScanner = [NSScanner scannerWith
我是一名优秀的程序员,十分优秀!