当前位置:  开发笔记 > 编程语言 > 正文

此表达式具有int类型,但此处与类型unit一起使用

如何解决《此表达式具有int类型,但此处与类型unit一起使用》经验,为你挑选了1个好方法。

我试图在F#中获得此vb.net代码的完全等效(不起作用):

Function FastPow(ByVal num As Double, ByVal exp As Integer) As Double
   Dim res As Double = 1
   If exp < 1 Then
      If exp = 0 Then Return res
      exp = -exp
      num = 1 / num
   End If
   Do While exp > 1
      If exp Mod 2 = 1 Then 
         res = res * num
      num = num * num
      exp = exp >> 1
   Loop
   Return res * num
End Function

我写了这个:

let FastPow num exp =
   let mutable ex = exp
   let mutable res = 1
   let mutable n = num
   if ex < 1 then
      if ex = 0 then res
      ex <- -ex
      n <- 1 / n
   while ex > 1 do
      if (ex % 2 = 1) then 
         res <- res * n
      n <- n * n
      exp >>> 1
   res * n

但在"如果ex = 0然后res"行中我得到一个错误:
"这个表达式有类型int但是在这里用于类型单位".我无法理解为什么它会给我这个错误.
编辑:我实际上也收到了一个警告:
"这个表达式应该有'unit'类型,但是类型为'int'."
at"if(ex%2 = 1)then"



1> Juliet..:

在F#中,函数的返回值是函数中计算的最后一个表达式.所以,让我们关注以下内容:

   if ex < 1 then
      if ex = 0 then res    (* <--- this is not an early return *)
      ex <- -ex             (* <--- F# evaluates this code after the *)
      n <- 1 / n            (*      if statement *)

此外,if语句具有返回值,这也恰好是if语句中执行的最后一个值.如果if语句不是函数的返回值,则它应该具有返回类型unit.请注意,变量赋值的返回类型为unit.

我们需要重写您的代码以适应您的早期回报,因此我们可以这样做:

let FastPow2 num exp =
    if exp = 0 then 1
    else
        let mutable ex = exp
        let mutable res = 1
        let mutable n = num
        if ex < 1 then
            ex <- -ex
            n <- 1 / n
        while ex > 1 do
            if (ex % 2 = 1) then  (* still have a bug here *)
                res <- res * n
            n <- n * n
            exp >>> 1  (* <--- this is not a variable assignment *)
        res * n

我们仍然有一个错误,虽然我认为F#在错误的地方报告错误.表达式exp >>> 1返回一个int,它不分配任何变量,因此它不等同于你原来的C#代码.我认为你的意思是使用ex变量.我们可以按如下方式修复您的代码:

let FastPow2 num exp =
    if exp = 0 then 1
    else
        let mutable ex = exp
        let mutable res = 1
        let mutable n = num
        if ex < 1 then
            ex <- -ex
            n <- 1 / n
        while ex > 1 do
            if (ex % 2 = 1) then 
                res <- res * n
            n <- n * n
            ex <- ex >>> 1
        res * n

现在你的功能是固定的,但它真的很难看.让我们把它转换成更惯用的F#.您可以使用模式匹配替换if语句,并使用递归替换while循环:

let FastPow2 num exp =
    match exp with 
    | 0 -> 1
    | _ ->
        let rec loop ex res n =
            if ex > 1 then
                let newRes = if ex % 2 = 1 then res * n else res
                loop (ex >>> 1) newRes (n * n)
            else res * n

        let ex, n = if exp < 1 then (-exp, 1 / num) else (exp, num)
        loop ex 1 n

好多了!还有一些空间来美化这个功能,但你明白了:)

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有