2022年2月15日 星期二

Go lang 學習筆記 - 17 Pointers

```
package main

import "fmt"

func zeroval(n int) {
        n = 0
}

func zeroptr(n *int) {
        *n = 0
}

func main() {
        i := 10
        fmt.Println("initial: ", i)

        zeroval(i)
        fmt.Println("value: ", i)

        zeroptr(&i)
        fmt.Println("pointer: ", i)

        fmt.Println("Address: ", &i)
}
```
Go 也有支援 pointer 的操作
寫起來跟 C 差不多

執行結果:

initial:  10

value:  10

pointer:  0

Address:  0xc0000140b8

2022年2月14日 星期一

Go lang 學習筆記 - 16 Recursion

```

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


2022年2月13日 星期日

Go lang 學習筆記 - 15 Closures

```

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


2022年2月12日 星期六

Go lang 學習筆記 - 14 Variadic Functions

```

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

2022年2月11日 星期五

買了虛擬貨幣只有放著等它漲? Binance(幣安) 活存教學 (幣安寶)

因為發現身邊不少人有在使用幣安

卻不知道幣安裡面有類似活存的理財工具

於是決定來寫一篇教學

本文的資料為寫文章的當下看到的利率(7%) 幣安的利率蠻常會調整的


首先打開手機版幣安  切換到專業版介面

簡潔版長這樣

(如果已經是專業版頁面就跳到下面專業版介面)

點選左上角紅色圈起來的地方

然後點選上面紅色圈的地方會開啟專業版頁面


專業版頁面會長的像下面這張圖

點右下角的資金  會看到下面的頁面



點選上方圈起來的"理財"

點最中間黃色的"申購幣安理財產品"

點了之後會看到下面的頁面 

這次我選用 USDT 當範例來操作一次

點選紅圈的 USDT 

注意下面有小字寫著幣安保活期  幣安寶活期可以當成銀行存款一樣  要使用可以隨時取消領出之類的


點下之後到申購頁面會長像下面那樣



第一個要注意的是金額限制寫著最少可投  代表你要活存的最低額度是多少

第二個要注意的是下面有 USDT APY 檔位費率 以下面的圖解說的話  
代表 0~2000 USDT算起來的年利率是 7%  
超過 2000 ~ 75000 的會算 3% 的利率
超過 75000 的利率是 0.5%

填好你要申購的金額後勾選下面的閱讀並同意協議

往下滑按下確認後可以看到下面的樣子

有一個特別的點是  下面紅色圈起來的地方可以考慮打開

打開的話會每天自動把你收到的利息再做申購  就可以有複利的效果




另外其他虛擬貨幣也有活存  例如下面附上當下 ETH 跟 BTC 的

如果確定自己不常動用那些幣的話可以放活存賺一點利息



如果覺得此篇文章有幫助  想註冊幣安的話歡迎使用我的推薦連結

https://accounts.binance.me/zh-TW/register?ref=U2AOEWOC

或是使用我的推薦碼註冊: U2AOEWOC


Go lang 學習筆記 - 13 多回傳值函式 (Multiple Return Values)

```

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


2022年2月10日 星期四

Go lang 學習筆記 - 12 Function

```

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

2022年2月9日 星期三

Go lang 學習筆記 - 11 Range

 ```

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

2022年2月8日 星期二

Go lang 學習筆記 - 10 Maps

 ```

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]

2022年2月7日 星期一

Go lang 學習筆記 - 9 Slices

 ```

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]]

2022年2月6日 星期日

Go lang 學習筆記 - 8 Arrays

``` 

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]]

2022年2月5日 星期六

Go lang 學習筆記 - 7 Switch

 

```

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

2022年1月31日 星期一

Go lang 學習筆記 - 6 If/Else

 這篇是練習 If-else 的用法 

```

package main


import "fmt"


func main() {

        if 7 % 2 == 0 {

                fmt.Println("7 is even")

        } else {

                fmt.Println("7 is odd")

        }


        if 8 % 4 == 0 {

                fmt.Println("8 is even")

        } else {

                fmt.Println("8 is odd")

        }


        if n := 9; n > 0 {

                fmt.Println("n is positive")

        } else if n < 0 {

                fmt.Println("n is negative")

        } else {

                fmt.Println("n is zero")

        }

}

```

比較特別的是可以用分號斷行

而且在condition statement (條件判斷式) 宣告的變數

可以在同一個If else裡面繼續使用

執行結果:

7 is odd

8 is even

n is positive

2022年1月30日 星期日

Go lang 學習筆記 - 5 For 迴圈

 練習基本的 for loop

```

package main


import "fmt"


func main() {

        i := 1

        for i < 3 {

                fmt.Println(i)

                i++

        }


        for j := 7; j < 10; j++ {

                fmt.Println(j)

        }


        for {

                fmt.Println("Infinitely loop")

                break

        }


        for n := 0; n < 5; n++ {

                if n % 2 == 0 {

                        continue

                }

                fmt.Println(n)

        }

}

```

Go lang 裡面的 for loop 不用小括號

但中間的分號用法是一樣的

輸出結果:

1

2

7

8

9

Infinitely loop

1

3

2022年1月29日 星期六

Go lang 學習筆記 - 4 常數 (Constant)

 接下來要練習使用常數 (constant)

程式碼如下

```

package main


import (

"fmt"

"math"

)


const s string = "constant"


func main() {

fmt.Println(s)


const n = 500000000


const d = 3e20 / n

fmt.Println(d)


fmt.Println(int64(d))


fmt.Println(math.Sin(n))

}

```

用法就是把 var 改成 const 其他沒什麼太大的差別

另外可以看到 go lang 的 type casting 語法跟 Python 比較相似

e.g. int64(d)

輸出結果:

constant

6e+11

600000000000

-0.28470407323754404

2022年1月28日 星期五

Go lang 學習筆記 - 3 變數 (Variables)

 接下來是練習變數的宣告及初始化

程式碼:

```

package main


import "fmt"


func main() {

var a = "initial"

fmt.Println(a)


var b, c int = 1, 2

fmt.Println(b, c)


var d = true

fmt.Println(d)


var e int

fmt.Println(e)


f := "string type"

fmt.Println(f)


}

```

原始的寫法應該是 

var <identifier list> <type> [ = <value list> ]


但是變數的初始化可以不給 type

compiler 會自行判斷


比較特別的是 

f := "string type"

這行相等於 

var f string = "string type"

一種同時宣告及初始化的簡便寫法


執行結果:

initial

1 2

true

0

string type

2022年1月27日 星期四

Go lang 學習筆記 - 2 數值運算

 第二個例子是基本的數值運算

程式碼如下:

```

package main


import "fmt"


func main() {

fmt.Println("go" + "lang")


fmt.Println("1+1 = ", 1+1)

fmt.Println("7.0/3.0  = ", 7.0/3.0)


fmt.Println(true && true)

fmt.Println(false || true)

fmt.Println(true)

}

```

String 的加法跟Python有點像

但語法跟 C 很類似


執行結果:

golang

1+1 =  2

7.0/3.0  =  2.3333333333333335

true

true

true

2022年1月26日 星期三

Go lang 學習筆記 - 1 Hello World

由於在網路上發現了 Go by Example 這個網站

所以短期目標就是讀完這些 Example 


第一個 Example 就是經典的 Hello World

然後因為我懶惰切換成 Linux 所以就直接在 https://go.dev/play/ 上練習了


Hello World 寫法如下

```

package main


import "fmt"


func main() {

    fmt.Println("Hello World")

}

```

第一行是宣告當前檔案為 main 的 package

Go lang 的 entry function 跟 C/C++ 一樣都是main

fmt.Println 目前理解起來像是 printf之類的  或是 cout


執行結果:

Hello, World

2022年1月25日 星期二

Go lang 學習筆記 - 0 安裝

 

 首先從安裝開始

 參考官方的文件 https://go.dev/doc/install

 下載最新Release的壓縮檔後執行以下指令

$ tar -C /usr/local -xzf go1.17.6.linux-amd64.tar.gz 
$ export PATH=$PATH:/usr/local/go/bin 
 
第二行指令會設定 go lang 的安裝路徑到 PATH 變數裡面 
但這只會有當下的 terminal 有效 下次重開又要執行上面的 export 一次才能使用
所以建議打開 ~/.profile 檔案
在最底下加上 
PATH=/usr/local/go/bin:$PATH
 
安裝好以後
執行
$ go version 
go version go1.17.6 linux/amd64 
會有上述的執行結果

2020年10月21日 星期三

自幹OS筆記 - 03 來個Hello World吧

一樣是寫程式  怎麼能不寫個Hello world呢?

所以接下來就是印個Hello world在螢幕上

BIOS 裡有提供簡單的 interrupt 可以完成這件事情

然後詳細的內容 可以翻閱 wikipedia 

簡單的說就是要設定 ax register 裡面的值 

分為 ah (高位址)和 al (低位址)

ah 設定成 0x0e 代表 Teletype output 會顯示 al 裡面存的ASCII code

--<boot.asm>---------------------------------------------------------------------

mov ah 0x0e

mov al, 'H'

int 0x10

mov al, 'e'

int 0x10

mov al, 'l'

int 0x10

mov al, 'l'

int 0x10

mov al, 'o'

int 0x10

mov al, ' '

int 0x10

mov al, 'w'

int 0x10

mov al, 'o'

int 0x10

mov al, 'r'

int 0x10

mov al, 'l'

int 0x10

mov al, 'd'

int 0x10

jmp $

times 510-($-$$) db 0x00

dw 0xaa55

-----------------------------------------------------------------------------------

簡單的說就是一個字一個字的填上去

然後 interrupt 讓字顯示上去

因為 ah 都一樣所以就不用動

填完之後 一樣一個 infinite loop

最後填上 0 跟 0xaa55就好了~

Go lang 學習筆記 - 17 Pointers

``` package main import "fmt" func zeroval(n int) {         n = 0 } func zeroptr(n *int) {         *n = 0 } func main() {         ...