作者 主題: Golang recursive & closure & 全域變數問題  (閱讀 963 次)

0 會員 與 1 訪客 正在閱讀本文。

Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4905
    • 檢視個人資料
    • http://www.ecmagic.com
今天在玩 Go 解 Sqrt() 碰到一個問題(今天第一次玩 Go,有誤請指正 ^__^)

Code:
代碼: [選擇]
package main
import (
  "fmt"
  "math"
)

var step int = 0;
var z float64 = 1.0;
var s float64 = 0.0;

func Sqrt(x float64) float64 {
  if step >= 12 {
    return x
  }
 
  if s == 0 {
    s = x
  }
 
  z = (z + s/z) / 2
  step++
  fmt.Println(z, x, step)
  Sqrt(z)
  return z
}

func main() {
  x := 12345.0;
 
  fmt.Println("Sqrt:");
  fmt.Println(Sqrt(x), "\n");

  fmt.Println(math.Sqrt(x));
}

Result:
引用
Sqrt:
6173 12345 1
3087.499919002106 6173 2
1545.7491498369006 3087.499919002106 3
776.8677842956971 1545.7491498369006 4
396.37925958974336 776.8677842956971 5
213.76183709549736 396.37925958974336 6
135.75651245108165 213.76183709549736 7
113.34568823712989 135.75651245108165 8
111.13014281250861 113.34568823712989 9
111.10805770848404 111.13014281250861 10
111.10805551354053 111.10805770848404 11
111.1080555135405 111.10805551354053 12
111.1080555135405

111.1080555135405

---
雖然有弄出來,只是有一點很不滿意,就是 Go 竟然未支援靜態變數!!!
所以上面有三個變數要宣告為全域變數,這樣真的很危險啊!!

後來看到有支援 closure 功能,於是就試了一下改成如下

Code:
代碼: [選擇]
func Sqrt2(x float64) float64 {
  step := 0;
  z := 1.0;
  s := x;
  var Sqrt func(float64) float64
 
  Sqrt = func(x float64) float64 {
    if step >= 12 {
      return x
    }
   
    z = (z + s/z) / 2
    step++
    fmt.Println(z, x, step)
    Sqrt(z)
    return z
  }
 
  return Sqrt(s);
}

func main() {
  x := 12345.0;
 
  fmt.Println("Sqrt:");
  fmt.Println(Sqrt(x), "\n");
 
  fmt.Println("Sqrt2:");
  fmt.Println(Sqrt2(x), "\n");
 
  fmt.Println(math.Sqrt(x));
}

Result:
引用
Sqrt2:
6173 12345 1
3087.499919002106 6173 2
1545.7491498369006 3087.499919002106 3
776.8677842956971 1545.7491498369006 4
396.37925958974336 776.8677842956971 5
213.76183709549736 396.37925958974336 6
135.75651245108165 213.76183709549736 7
113.34568823712989 135.75651245108165 8
111.13014281250861 113.34568823712989 9
111.10805770848404 111.13014281250861 10
111.10805551354053 111.10805770848404 11
111.1080555135405 111.10805551354053 12
111.1080555135405

這樣就可以將原來的全域變數改成區域變數
當然,執行結果完全相同 ^____^



netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17300
    • 檢視個人資料
    • http://www.study-area.org
Re: Golang recursive & closure & 全域變數問題
« 回覆 #1 於: 2015-07-17 11:34 »
感謝分享!