F# 编译器错误 "This expression was expected to have type unit but here has type bool." {if else} 语句中的表达式
F# compiler error "This expression was expected to have type unit but here has type bool." expression in {if else} statements
我用F#写过这样的函数:
let TwistBasket (reverse: bool, quarters: int, overTwist: int byref) =
overTwist <- 50
WaitForBasketReady()
waitBasket.Reset()
let move = 135*quarters - 25 + overTwist
let speed =
match reverse with
| true -> -75y
| false -> 75y
let waitHandle = motorBasket.SpeedProfile(speed, 15u, uint32 move, 10u, true)
Task.Factory.StartNew(fun () ->
waitHandle.WaitOne()
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
waitBasket.Set()
关于这个 if 语句;
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
我收到错误:This expression was expected to have type unit but here has type bool.
实际上motorBasket.SpeedProfile().WaitOne()
返回布尔语句。我需要它。
因为我试图在 C# 中转换这个 if else 语句:
Task.Factory.StartNew(() =>
{
waitHandle.WaitOne();
if (overTwist != 0)
{
motorBasket.SpeedProfile((sbyte) -speed, 0, (uint) overTwist, 0, true).WaitOne();
}
waitBasket.Set();
});
如何解决我的错误?
通过查看 C# 版本,它对结果没有任何作用。所以在 F# 中我会调用 ignore
这将 eat 结果:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne() |> ignore
F# 在这些情况下比 C# 更严格,如果您的 if .. then 没有 else 分支,结果应该是 unit , 这很有道理。
您还可以创建一个带有(虚拟)布尔值的 else 分支并将其绑定到一个(虚拟)值,但在这种特殊情况下,如果您真的不打算使用该值,那意义何在?您真正在做的是产生副作用并忽略结果,F# 驱使您在代码中使其更加明确。
在 F# 中 if/else
表达式应该具有相同的类型。如果您使用不带 else
分支的 if
表达式,则 F# 编译器会隐式认为 else
分支具有类型 unit
,因此会出现错误。
您可以更改代码以显式使用 else 分支:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
else
... // Put here expression of the same type as if (I assume it's bool)
或者您可以像 Gustavo 提到的那样在 if 分支中使用 ignore
函数。
我用F#写过这样的函数:
let TwistBasket (reverse: bool, quarters: int, overTwist: int byref) =
overTwist <- 50
WaitForBasketReady()
waitBasket.Reset()
let move = 135*quarters - 25 + overTwist
let speed =
match reverse with
| true -> -75y
| false -> 75y
let waitHandle = motorBasket.SpeedProfile(speed, 15u, uint32 move, 10u, true)
Task.Factory.StartNew(fun () ->
waitHandle.WaitOne()
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
waitBasket.Set()
关于这个 if 语句;
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
我收到错误:This expression was expected to have type unit but here has type bool.
实际上motorBasket.SpeedProfile().WaitOne()
返回布尔语句。我需要它。
因为我试图在 C# 中转换这个 if else 语句:
Task.Factory.StartNew(() =>
{
waitHandle.WaitOne();
if (overTwist != 0)
{
motorBasket.SpeedProfile((sbyte) -speed, 0, (uint) overTwist, 0, true).WaitOne();
}
waitBasket.Set();
});
如何解决我的错误?
通过查看 C# 版本,它对结果没有任何作用。所以在 F# 中我会调用 ignore
这将 eat 结果:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne() |> ignore
F# 在这些情况下比 C# 更严格,如果您的 if .. then 没有 else 分支,结果应该是 unit , 这很有道理。
您还可以创建一个带有(虚拟)布尔值的 else 分支并将其绑定到一个(虚拟)值,但在这种特殊情况下,如果您真的不打算使用该值,那意义何在?您真正在做的是产生副作用并忽略结果,F# 驱使您在代码中使其更加明确。
在 F# 中 if/else
表达式应该具有相同的类型。如果您使用不带 else
分支的 if
表达式,则 F# 编译器会隐式认为 else
分支具有类型 unit
,因此会出现错误。
您可以更改代码以显式使用 else 分支:
if (overTwist <> 0) then
motorBasket.SpeedProfile(sbyte -speed, 0u, uint32 overTwist, 0u, true).WaitOne()
else
... // Put here expression of the same type as if (I assume it's bool)
或者您可以像 Gustavo 提到的那样在 if 分支中使用 ignore
函数。