为什么 unsafe { x } == y 不编译?

huangapple go评论77阅读模式
英文:

Why does unsafe { x } == y not compile?

问题

I'm getting some compile errors in something I believe it should work:

fn function() -> bool {
    unsafe { 1 } == 1
}
error: expected expression, found `==`
 --> src/main.rs:9:18
  |
9 |     unsafe { 1 } == 1
  |                  ^^ expected expression

error[E0308]: mismatched types
 --> src/main.rs:9:14
  |
9 |     unsafe { 1 } == 1
  |              ^ expected `()`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `testcon` due to 2 previous errors

I get that this is kind of useless, but that 1 is really an unsafe function.
But then this works just fine.

fn function() -> bool {
    let var = unsafe { 1 };
    var == 1
}

I get that maybe both will be optimized to be exactly the same, but I'm curious about the why.

英文:

I'm getting some compile errors in something I believe it should work:

fn function() -> bool {
    unsafe { 1 } == 1
}
error: expected expression, found `==`
 --> src/main.rs:9:18
  |
9 |     unsafe { 1 } == 1
  |                  ^^ expected expression

error[E0308]: mismatched types
 --> src/main.rs:9:14
  |
9 |     unsafe { 1 } == 1
  |              ^ expected `()`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `testcon` due to 2 previous errors

I get that this is kind of useless, but that 1 is really a unsafe function.
But then this works just fine.

fn function() -> bool {
    let var = unsafe { 1 };
    var == 1
}

I get that maybe both will be optimized to be exactly the same but I'm curious about the why

答案1

得分: 5

问题在于unsafe是一种块表达式,因此当它出现在语句开头时,我们可以省略末尾的分号,但这意味着它被解析为一个完整的语句,我们不能将其用作表达式的一部分。这在参考文档中有提到

如果一个只包含块表达式或控制流表达式的表达式在允许语句的上下文中使用,可以省略尾随的分号。这可能会导致它被解析为一个独立的语句和另一个表达式的一部分之间的歧义;在这种情况下,它被解析为一个语句。

修复方法是将其放在括号中:

fn function() -> bool {
    (unsafe { 1 }) == 1
}
英文:

The problem is that unsafe is a kind of block expression, so when it appears at the beginning of a statement we can omit the semicolon at the end, but this means it is parsed as a whole statement and we cannot use it as part of an expression. This is mentioned in the reference:

> An expression that consists of only a block expression or control flow expression, if used in a context where a statement is permitted, can omit the trailing semicolon. This can cause an ambiguity between it being parsed as a standalone statement and as a part of another expression; in this case, it is parsed as a statement.

The fix is to wrap it in parentheses:

fn function() -> bool {
    (unsafe { 1 }) == 1
}

huangapple
  • 本文由 发表于 2023年5月21日 03:23:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76296991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定