- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下是我可以用 Rust 1.23.0 编译的有效文件:
fn main() {
let r = String::from("a");
let a = Some(&r);
let b = match a {
Some(name) => name,
None => "",
};
println!("{}", b);
}
虽然下面的代码
fn main() {
let r = String::from("a");
let a = Some(&r);
let b = a.unwrap_or("");
println!("{}", b);
}
失败并出现错误:
error[E0308]: mismatched types
--> src/main.rs:4:25
|
4 | let b = a.unwrap_or("");
| ^^ expected struct `std::string::String`, found str
|
= note: expected type `&std::string::String`
found type `&'static str`
据我所知,编译器在此处确定类型时的推理如下:
在 match
的情况下,它确定 b
是一个 &str
,因为 None => ""
是一个 &str
而 Some(name) => name
是一个 &String
所以它可以变成一个 &str
.
如果 unwrap_or
的参数是 &str
,而不是将 b
键入为 &str
,它发现 a
中保存的类型(即 &String
)和 unwrap_or
的参数类型之间存在差异。
使类型推导以这种方式工作的这两种情况有什么区别?
unwrap_or
是否实现为接受与选项包装的类型完全相同的类型,而不是只接受它放在匹配项中的通用值?
此外,有什么方法可以使 unwrap_or
在这种情况下工作,而不必在外部范围内声明 String
或更改选项包装的类型?
我在其他地方得到的一个让它们工作的答案是这样的:
let b = a.map(|s| s.as_ref()).unwrap_or("")
与 match
的效果相同,但比 match
更短,更明确地说明类型发生了什么。
最佳答案
粗略地说,你只对了一半。
a
是一个 Option<&String>
.一个&String
可以强制转换为 &str
,而是一个 &str
不能强制转换为 &String
.看这段代码:
fn main() {
let a = String::from("This is a String");
let a_r = &a;
foo(a_r);
bar(a_r);
let b = "This is an &str";
// Next line will cause a compilation error if uncommented
// foo(b);
bar(b);
}
fn foo(s: &String) {
println!("Foo: {}", s);
}
fn bar(s: &str) {
println!("Bar: {}", s);
}
如果foo(b);
未注释,它会告诉您它预期 String
, 得到 str
.
match
语句返回 &str
(从 &String
转换而来),但是 unwrap_or
期望与 Option
相同的类型你打电话的是一个&String
, 这是 &str
没有手动更改就无法成为( String::from
、 to_string
、 to_owned
等)
现在,我将尝试对原因做一个简短的解释,但请持保留态度,因为我不是该领域的专家 .
当使用字符串文字 ( "foo"
) 时,程序在编译时会创建一些内存段,以二进制形式表示此文本。这就是为什么字符串文字是 &str
的原因而不仅仅是 str
: 它不是原始文本,而是对启动时已经存在的文本的引用。这意味着字符串文字位于内存的特定部分,无法修改,因为它们挤在其他对象旁边 - ( "fooquxegg"
) - 并试图向字符串文字添加字符会导致您覆盖行中的下一个对象,这是非常糟糕的。
A String
, 但是,是可以修改的。由于我们无法确定一个字符串中有多少个字符,它必须存在于“堆”中,如果某些东西试图“长成”其他东西,则对象可以在堆中移动,并且String
type 基本上用作指向堆中该文本的指针,很像 Box<T>
指向 T
在堆中。
因此,虽然 &String
可以变成&str
(它指向一定数量的文本某处,在这种情况下,是堆中的某处而不是静态内存),&str
不能保证成为 &String
.如果您将驻留在无法修改的内存部分中的字符串文字(如我们的 "foo"
)转换为 &String
。 可能会被修改,然后尝试向其附加一些字符(例如 "bar"
),它会覆盖其他内容。
话虽如此,请看这段代码:
fn main() {
let s = "this is an &str";
let b = String::from("this is a String");
let s_o : Option<&str> = Some(s);
let s_or_def = s_o.unwrap_or(&b);
println!("{}", s_or_def);
}
此代码实际上是您的 unwrap_or
的反函数示例:一个 Option<&str>
正在用 &String
展开作为默认值。这将编译,因为 &String => &str
是一个有效的转换,编译器将自动插入必要的转换而不需要它是显式的。所以不,unwrap_or
没有实现接受完全相同的对象类型;任何可以强制转换为 T
的对象(在这种情况下,T
是 &str
)是有效的。
换句话说,你的 unwrap_or
示例失败,因为 一个 &str
不能成为 &String
,而不是因为 unwrap_or
方法异常挑剔。不,可能没有办法 unwrap_or
不使用 String
.你最好的选择是简单地使用 to_string
在字符串文字上,按照:
fn main() {
let s = String::from("Hello, world!");
let o = Some(s);
let r = o.unwrap_or("Goodbye, world!".to_string());
println!("{}", r);
}
因为 map_or
,虽然看起来很有前途,但不会简单地让您输入 |s| &s
对于 map (引用在闭包末尾被丢弃)。
关于generics - 确定类型时 match 和 unwrap_or 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49396869/
我正在尝试为匹配中的每个匹配呈现一些 HTML,但是,我不太确定 实际上是正确的。 更具体地说,我不确定我是否可以使用 v-bind:match='match'在与循环相同的元素上 v-for='ma
它具有看似简单的代码: method match(Any:U: |) { self.Str; nqp::getlexcaller('$/') = Nil } 但是,这是它的行为: (^3).matc
如果您想检查某项是否与正则表达式匹配,如果是,请打印第一组,您就可以了.. import re match = re.match("(\d+)g", "123g") if match is not N
以下两个查询的结果有差异吗? SELECT * FROM table1, table2 WHERE ( MATCH(table1.row1) AGAINST('searchstring' IN
我正在尝试为我的日志文件创建一个语法文件。它们采用以下格式: [time] LEVEL filepath:line - message 我的语法文件如下所示: :syn region logTime
String#match 和 Regexp#match 在匹配成功时返回一个 MatchData: "".match(//) # => # //.match("") # => # //.match(:
我的代码中有这个函数: func match(match: GKMatch, player playerID: String, didChangeState state: GKPlayerConnec
我对 match 和 case 之间的区别感到困惑。在 document ,其中提到match支持通用模式匹配。 > (define (m x) (match x [(list a
我在检查特定元素中的空 HTML 内容时遇到了问题。当我使用 someElement.trim().match("") 即使 HTML 内容为空,我有时也会得到 true。我改成了 someEleme
我正在尝试使用正则表达式查找包含特定词的两个词之间的所有内容,但是这些词是重复的,所以我没有得到我想要的匹配项。 例如,我想要“你好”和“再见”之间的所有内容,以便它们之间存在“苹果”一词: hell
我目前正在构建一个 PHP 脚本,它将在需要时响应 HTTP“304 Not Modified”。 (请参阅 question #2086712 了解我目前所做的事情)。 目前我回答以下问题: If-
给定以下 XML 10 我希望能够正确识别内部 的 s : result = subject.gsub(/]*>)/, '<') 解释: ]* # any number of charact
这个问题在这里已经有了答案: How to error handle 1004 Error with WorksheetFunction.VLookup? (3 个回答) 3年前关闭。 目标:查找输入
我已经尝试了好一阵子了,但是我似乎无法弄清楚这两者之间的区别。特别是,与数据数组有关的差异: PS C:>$myarray = "a", "ab", "abc" PS C:>$myarray -mat
我正在努力研究如何构建一个宏,让我可以将模式和结果以向量的形式传递给 core.match/match 。我希望能够做到这一点: (let [x {:a 1} patterns [[{:a
这个问题在这里已经有了答案: Reference - What does this regex mean? (1 个回答) 关闭 8 年前。 如果这看起来微不足道但只是为了理解正则表达式,请原谅我:
我的 MySQL 表中有大约 20 行,其 Title 列为 Elsewhere 并具有其他不同的列参数。 我目前正在使用这样的查询,因为我的大多数搜索(通过 PHP 文件)都需要我进行猜测。所以我使
当找到匹配时,我必须从字符串中删除单词 让我们看看 我的输入字符串是 “肯诺克斯路” 比赛表演中的单词表 街道 驾驶 道路 4. 车道 输出字符串应该是: KENOX 我正在使用 vb.net 作为此
我正在搜索以下形式的字符串模式: XXXAXXX # exactly 3 Xs, followed by a non-X, followed by 3Xs 所有的 X 必须是相同的字符,并且 A 不能
好吧,我是 gulp 和 sass 的新手,我正在努力让它发挥作用。我正确安装了所有东西,但我收到了这个愚蠢的错误。有解决办法吗? PS C:\Users\Bojan Kolano\Desktop\F
我是一名优秀的程序员,十分优秀!