initial: 10
value: 10
pointer: 0
Address: 0xc0000140b8
initial: 10
value: 10
pointer: 0
Address: 0xc0000140b8
```
package main
import "fmt"
func fact(n int) {
if n == 0 {
return 1
}
return n * fact(n - 1)
}
func main() {
fmt.Println(fact(7))
var fib(n int) int
fib = func(n int) int {
if n < 2 {
return n
}
return fib(n-1) + fib(n-2)
}
fmt.Println(fib(7))
}
```
遞迴的寫法就照正常樣子 如上面的 fact()
但網頁中寫 fib() 的描述如下
Closures can also be recursive, but this requires the closure to be declared with a typed
var
explicitly before it’s defined.
但我看不出來 fib 是 closure
所以... 以後如果有看出來再補充
執行結果:
5040
13
```
package main
import "fmt"
func intSeq() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
nextInt := intSeq()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
nextInt2 := intSeq()
fmt.Println(nextInt2())
}
```
Closure 的概念我也是第一次學到 查了一些資料
我的理解是 把變數包進 anonymous function 裡面使用的話
The anonymous function close over the variable
等於會延長該變數的生命週期(lifetime) 直到 anonymous function 生命週期結束
然後特殊的是每個 anonymous function 裡面包的變數是獨立的
例如上面的 nextInt 跟 nextInt2 兩個裡面的 i 是不同的
執行結果:
1
2
3
1
```
package main
import "fmt"
func sum(nums ...int) {
fmt.Print(nums, " ")
total := 0
for _, num := range nums {
total += num
}
fmt.Println(total)
}
func main() {
sum(1, 2)
sum(1, 2, 3)
nums := []int{1, 2, 3, 4}
sum(nums...)
}
```
Go 也可以接受不定長度的參數
用法如上
如果要傳遞不定長度參數給function 而不是傳 array 本身要在呼叫的時候加上 "..."
執行結果:
[1 2] 3
[1 2 3] 6
[1 2 3 4] 10
因為發現身邊不少人有在使用幣安
卻不知道幣安裡面有類似活存的理財工具
於是決定來寫一篇教學
本文的資料為寫文章的當下看到的利率(7%) 幣安的利率蠻常會調整的
首先打開手機版幣安 切換到專業版介面
簡潔版長這樣
(如果已經是專業版頁面就跳到下面專業版介面)
點選左上角紅色圈起來的地方
然後點選上面紅色圈的地方會開啟專業版頁面
專業版頁面會長的像下面這張圖
點右下角的資金 會看到下面的頁面
點選上方圈起來的"理財"
點最中間黃色的"申購幣安理財產品"
點了之後會看到下面的頁面
這次我選用 USDT 當範例來操作一次
點選紅圈的 USDT
注意下面有小字寫著幣安保活期 幣安寶活期可以當成銀行存款一樣 要使用可以隨時取消領出之類的
點下之後到申購頁面會長像下面那樣
往下滑按下確認後可以看到下面的樣子
有一個特別的點是 下面紅色圈起來的地方可以考慮打開
打開的話會每天自動把你收到的利息再做申購 就可以有複利的效果
另外其他虛擬貨幣也有活存 例如下面附上當下 ETH 跟 BTC 的
如果確定自己不常動用那些幣的話可以放活存賺一點利息
如果覺得此篇文章有幫助 想註冊幣安的話歡迎使用我的推薦連結
https://accounts.binance.me/zh-TW/register?ref=U2AOEWOC
或是使用我的推薦碼註冊: U2AOEWOC
```
package main
import "fmt"
func vals() (int, int) {
return 3, 7
}
func main() {
a, b := vals()
fmt.Println(a)
fmt.Println(b)
_, c := vals()
fmt.Println(c)
}
```
Go 支援回傳多個值 寫法就如上面所述
執行結果:
3
7
7
```
package main
import "fmt"
func plus(a int, b int) int {
return a + b
}
func plusPlus(a, b, c int) int {
return a + b + c
}
func main() {
res := plus(1, 2)
fmt.Println("1+2=", res)
res = plusPlus(1, 2, 3)
fmt.Println("1+2+3=", res)
}
```
Function 的寫法比較特別的就是 return type 在最後面
其他沒什麼比較特別的東西
執行結果:
1+2= 3
1+2+3= 6
```
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
sum := 0
for idx, num := range nums {
sum += num
fmt.Println("idx, val: ", idx, num)
}
fmt.Println("sum: ", sum)
kvs := map[string]string{"a": "apple", "b": "banana"}
for k,v := range kvs {
fmt.Println("%s -> %s", k, v)
}
for k := range kvs {
fmt.Println("key: ", k)
}
for i, c := range "go" {
fmt.Println(i, c)
}
}
```
Go 裡面 Range 的用法跟 Python 的 enumerate 有點像
如果是普通的 array 會一個一個列舉而且有 index
如果是 str 的話 value 會是 unicode
執行結果:
idx, val: 0 2
idx, val: 1 3
idx, val: 2 4
sum: 9
%s -> %s a apple
%s -> %s b banana
key: a
key: b
0 103
1 111
```
package main
import "fmt"
func main() {
m := make(map[string]int)
m["k1"] = 7
m["k2"] = 12
fmt.Println("map: ", m)
v1 := m["k1"]
fmt.Println("v1: ", v1)
fmt.Println("len: ", len(m))
delete(m, "k2")
fmt.Println("map: ", m)
_, present := m["k2"]
fmt.Println("present: ", present)
n := map[string]int{"foo": 1, "bar": 2}
fmt.Println("map n: ", n)
}
```
Map 的用法跟 Python 的 dict 差不多
只是寫法不太一樣
比較特別的是 拿值的時候有第二個回傳值
可以用來判斷 key 有沒有在map裡面
執行結果:
map: map[k1:7 k2:12]
v1: 7
len: 2
map: map[k1:7]
present: false
map n: map[bar:2 foo:1]
```
package main
import "fmt"
func main() {
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("set: ", s)
fmt.Println("get: ", s[2])
fmt.Println("len: ", len(s))
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println("apd: ", s)
c := make([]string, len(s))
copy(c, s)
fmt.Println("copy: ", c)
l := s[2:5]
fmt.Println("slic1: ", l)
l = s[:5]
fmt.Println("slic2: ", l)
l = s[2:]
fmt.Println("slic3: ", l)
twoD := make([][]int, 3)
for i := 0; i < 3; i++ {
innerLen := i + 1
twoD[i] = make([]int, innerLen)
for j := 0; j < innerLen; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2D: ", twoD)
}
```
Slice 的操作跟 Python 的用法很相似
比較特別的是用 make 先產生固定長度的 array (有點像是 C++ 的 new 但不需要delete )
然後在二維陣列(2D array)的 make 第二個參數指定的只有第一層的長度
內層 array 的長度可以不一樣
執行結果:
set: [a b c]
get: c
len: 3
apd: [a b c d e f]
copy: [a b c d e f]
slic1: [c d e]
slic2: [a b c d e]
slic3: [c d e f]
2D: [[0] [1 2] [2 3 4]]
```
package main
import "fmt"
func main() {
var a [5]int
fmt.Println(a)
a[4] = 100
fmt.Println("set: ", a)
fmt.Println("get: ", a[4])
fmt.Println("len: ", len(a))
b := [5]int{1, 2, 3, 4, 5}
fmt.Println("decl: ",b )
var twoD [2][3]int
fmt.Println("2D arr: ", twoD)
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2D arr: ", twoD)
}
```
Array 的語法跟 C 不一樣的地方是把 維度放在型別前面
而 C 是放在 identifier 後面
執行結果:
[0 0 0 0 0]
set: [0 0 0 0 100]
get: 100
len: 5
decl: [1 2 3 4 5]
2D arr: [[0 0 0] [0 0 0]]
2D arr: [[0 1 2] [1 2 3]]
```
package main
import (
"fmt"
"time"
)
func main() {
i := 2
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("It's weekend.")
default:
fmt.Println("It's weekday.")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
whatAmI := func(i interface{}) {
switch t := i.(type) {
case bool:
fmt.Println("It's bool type")
case int:
fmt.Println("It's int type")
default:
fmt.Printf("Don't unknown type %T\n", t)
}
}
whatAmI(true)
whatAmI(6)
whatAmI("hey")
}
```
Switch 的用法跟 C 也是差不多
只是範例中多了 i.(type) 的用法來得到變數(可能也有常數)的型別(type)
執行結果:
two
It's weekday.
It's after noon
It's bool type
It's int type
Don't unknown type string
``` package main import "fmt" func zeroval(n int) { n = 0 } func zeroptr(n *int) { *n = 0 } func main() { ...