Iris 這個在 go 語言上地表最快的網頁框架-延遲執行

延遲執行

說明完指標、方法、類別與介面後我們再回到關於 go 的方法流程的介紹, go 流程是由上而下逐步執行,但是這只是通則而已,因為接下來要介紹的內容如,多執行續以及本篇要說明的延遲執行 defer 則是例外,本篇會先說明延遲執行的內容。

閱讀全文〈Iris 這個在 go 語言上地表最快的網頁框架-延遲執行〉

Iris 這個在 go 語言上地表最快的網頁框架-指標、類別與方法

go 的指標、類別與方法

在前面的內容分別跟大家分享 go 的指標、類別與方法,讓大家瞭解如何在 go 語言中使用指標、類別與方法撰寫商業邏輯,不過光瞭解指標、類別與方法的宣告實作與使用很容易造成誤用,還有分別介紹有沒有提及如何搭配使用,所以本篇要針對這兩點來說明指標的優缺點,還有如何撰寫指標、類別的方法。

閱讀全文〈Iris 這個在 go 語言上地表最快的網頁框架-指標、類別與方法〉

Iris 這個在 go 語言上地表最快的網頁框架-介面的宣告及使用

go 的介面

在前一篇文章介紹給大家如何在 go 語言內寫方法,有了方法就可以把相同的邏輯抽成共用的方法,讓同一件事情可以重複呼叫共同的方法來處理,但是如果要更進一步的說道程式設計不能不提到物件導向,前面也有大致上說明 go 的物件導向,所以這一篇要開始跟大家說明 go 的介面。
閱讀全文〈Iris 這個在 go 語言上地表最快的網頁框架-介面的宣告及使用〉

Iris 這個在 go 語言上地表最快的網頁框架-迴圈的語法

go 迴圈的語法

在介紹完 go 的邏輯判斷的之後接下來要跟大家分享一下 go 迴圈的語法,這部分內容與大部分語言相同,本來筆者想這樣告訴大家,但是其實 go 只有一個for,所以接下來筆者會說明如何用一個for來完成其他語言的forforeachwhile這種迴圈判斷式。

go 的 for迴圈

因為 go 的迴圈語法只有for一種所以接下來會以其他語言的forforeachwhile來解釋如何在 go 裡面完成。

for

所以先針對for迴圈的寫法來介紹,請大家看一下以下例子

package main

import "fmt"

func main() {
    sum := 0
    for i := 0; i < 10; i++ {
        sum += i
    }
    fmt.Println(sum)
}

看上述例子其實與其他語言差異不大,簡單講就是for ; ; {}的結構for與第一個;for迴圈的初始設定,兩個;之間是for迴圈的判斷式,;{則是判斷是不成立時要做的工作而{}之間則是在為滿足時執行的程式。在說明完for迴圈後要介紹foreach的寫法。

foreach

在 go 沒有foreach的語法,不過還是可以做到foreach的工作,關於如何處理foreach請看下列例子

package main

import "fmt"

func main() {

    numbers := []int{1,2,3,4,5,6,7,8,9}

    for _, number:= range numbers {
        fmt.Println("The number is:", number)
    }
}

讀者可以看到這例子調用range這個語法跟_這個語法,首先先解釋_這個語法,由於在foreach之中不需要初始化所以用一個_來接他,而這個_專門拿來放不需要的東西。接下來range就是用在迭代容器中的元素,如此就可以完成foreach的語法,所以如果今天想要依序跑map裡面的元素也可以用這種方式,如下列所示

package main

import "fmt"

func main() {

    numbers := map[string]int{"One":1,"Two":2,"Three":3}

    for k, number:= range numbers {
        fmt.Println("The ", k, " is:", number)
    }
}

原來在之前slice的例子中我們忽略的元素是index,但是在map中也許會使用到,所以在這裡用k來接他,在mapk所取到的就是key,如果在slice需要index的話也可以用變數來接他,這部分就不贅述了,接下來就說明一下如何處理while

while

在 go 語言中只有for迴圈沒有while迴圈那是因為for迴圈就能處理while迴圈的工作了,請看以下例子

package main

import "fmt"

func main() {
    sum := 1
    for sum < 1000 {
        sum += 1
    }
    fmt.Println(sum)
}

上述例子是實作當sum加總到1000就停止的while迴圈,所以寫法與其它語言差不多,只不過是用for關鍵字,那讀者會好奇while(true)要怎麼實作呢,請看以下例子

package main

func main() {
    for {
    }
}

簡單說明就是for之後不帶任何判斷式即可。

結論

這篇文章說明 go 的迴圈判斷式要如何使用,並且點出 go 語言的迴圈判斷式與其它語言不同的地方。在說明完迴圈判斷式之後要進入如何在 go 裡面寫方法了。

Iris 這個在 go 語言上地表最快的網頁框架-邏輯判斷語法

go 的邏輯判斷語法

在介紹完 go 的變數以及容器,接下來要開始進入程式邏輯判斷的部分,這部分內容與大部分語言相同,不外乎就是ifelseswitch相關的語法,所以接下來針對這細節部分加以說明。

邏輯判斷語法的說明

前面有針對邏輯判斷的語法做一個初步的介紹,所謂邏輯判斷語法不外乎就是ifelseswitch,所以接下來分別針對期內容作細部的說明。

if

這部分就是簡單的如果判斷是,如果成立就會執行區塊內的程式,請見以下例子

package main

import (
    "fmt"
)

func main() {
    odd := 11
    mod := odd % 2
    if mod != 0{
        fmt.Println(odd, "is odd")
    }
}

上面就是一個簡單的if判斷式的例子,其中當if後面條件成立時就會執行{}內的程式,然而還可以寫成下面例子

package main

import (
    "fmt"
)

func main() {
    odd := 11
    if mod := odd % 2; mod != 0{
        fmt.Println(odd, "is odd")
    }
}

簡單講就是將賦值,與判斷寫在同一個區塊,再以;分隔開來,當;後面的判斷成立時就會執行{}的程式。

else

在介紹完if接下來跟大家介紹else,簡單說明else就是當if不成立時會判斷的其他條件,當條件成立時會執行區塊內的程式。詳細請看以下例子

package main

import "fmt"

func main() {
    v := 4
    if v == 1 {
        fmt.Printf("%d is 1", v)
    } else if v == 2 {
        fmt.Printf("%d is 2", v)
    } else if v ==3 {
        fmt.Printf("%d is 3", v)
    } else {
        fmt.Printf("%d is else", v)
    }
}

這裡要注意格式,若是與上面例子不相符會導致於編譯錯誤的問題,同時這部分也可以再if加入賦值的需求然後再;後面加入判斷式,詳細請看以下例子

package main

import "fmt"

func main() {
    o := 10

    if v := o%3;v == 1 {
        fmt.Printf("%d is 1", v)
    } else if v == 2 {
        fmt.Printf("%d is 2", v)
    } else if v ==3 {
        fmt.Printf("%d is 3", v)
    } else {
        fmt.Printf("%d is else", v)
    }
}

再例子內v這變數只存在ifelse的判斷式之內,所以拿到底下使用會造成編譯失敗的狀況。到目前為止ifelse的介紹將告一段落,接下來要介紹switch的判斷式。

switch

就如同ifelse一樣,switch的判斷式是檢查變數是否與case後的值相同,當相同就會執行區塊內的程式,詳細請看下列例子

package main

import "fmt"

func main() {
    switch os := "Other"; os {
    case "First":
        fmt.Println("First.")
    case "Second":
        fmt.Println("Second.")
    default:
        // freebsd, openbsd,
        // plan9, windows...
        fmt.Printf("%s.\n", os)
    }
}

以上例子主要是在switch後面有一個賦值的式子接下來以;來區隔,在;後是接著要判斷的變數go,而case後是放著比對的內容,如果go的內容與case後的值相同則會執行casecase之間的程式,如果最後都沒成立會執行default的程式,還有比較特別的地方是對於go而言casecase之間不需要break隔開。但是以下例子就會造成邏輯判斷錯誤

package main

import "fmt"

func main() {
    switch os := "Second"; os {
    case "First":
    case "Second":
        fmt.Println("First and Second.")
    default:
        // freebsd, openbsd,
        // plan9, windows...
        fmt.Printf("%s.\n", os)
    }
}

那要如何修改上述例子呢,就把他當ifelse來使用即可,就是不要在switch給條件式,而在case內寫判斷式,如下列例子所示

package main

import "fmt"

func main() {
    os := "Fourth"
    switch  {
    case os == "First" || os == "Second":
        fmt.Println("First and Second.")
    case os == "Third" || os == "Fourth":
        fmt.Println("Third and Fourth.")
    default:
        // freebsd, openbsd,
        // plan9, windows...
        fmt.Printf("%s.\n", os)
    }
}

除了上述的例子之外switch還有一個要注意的點是,判斷式的順序是由上而下,如果其中一個case成立後就會執行其中的程式並且離開switch判斷式。

結論

這篇的內容主要是介紹 go 的邏輯判斷式,並跟大家分享一下 go 的邏輯判斷式與其他語言的差異。接下來下一篇要開始跟大家分享 go 的迴圈判斷式。

Iris 這個在 go 語言上地表最快的網頁框架-容器的類別

go 的容器

在介紹完變數的宣告與賦值之後要來介紹 go 語言之中的容器,相信有些程式基礎的讀者在認識完有哪些基礎型別後就會先看一下該語言有提供那些容器可供使用,所以接下來就要介紹 go 的容器arrayslicemap

容器的類別

接下來要分別針對 go 的容器類型加以說明,首先先說明大家比較熟悉的 array

array

這個翻譯叫陣列的容器是最常用的容器,但是這個容器在宣告時就要指定大小,所以使用的方法如下

package main

import "fmt"

func main() {
    var a [2]string
    a[0] = "Hello"
    a[1] = "World"
    fmt.Println(a[0], a[1])
    fmt.Println(a)

    primes := [6]int{2, 3, 5, 7, 11, 13}
    fmt.Println(primes)
}

上面例子的aprimes就是array,其使用的方法就是要[]中間要有個大於零的整數,在賦值之後可以使用[start:end]取得容器內從startend的另外一個array的記憶體位置。儘管array的大小是固定的但是 go 有提供方法可以來轉換成下一種容器。

slice

介紹完上一個容器後接著介紹比較常用的容器slice期差別就如同剛剛講的array大小固定、slice

可以擴充大小,接下來先看看用法

package main

import "fmt"

func main() {
    primes := [6]int{2, 3, 5, 7, 11, 13}

    var s []int = primes[1:4]
    fmt.Println(s)
}

上面例子中的s就是slice,其使用的方法就是要[]中間不需要帶數字,在 go 裡面關於slice的初始化的方式如下

package main

import "fmt"

func main() {
    s := make([]int, 5) // make an int slice of length 5
    fmt.Println(s) // [0 0 0 0 0]
        s2 := []int{0,0,0,0,0}
    fmt.Println(s2) // [0 0 0 0 0]
}

上面的make是產生一個大小為5的slice,而另外一種是直接給定5個0的slice然而光這樣說明對於使用者的使用上來說還太簡陋,接下來要說明如何擴展容器

package main

import "fmt"

func main() {
    a := []int{1,2,3}
    b := []int{4,5,6}
    c := append(a,b...)
    fmt.Println(c)
    d := append(a, 1)
    fmt.Println(d)
}

上面的例子簡單來說就是將a,b都放到c裡面。說完了如何擴充之後接下來就要說明如何刪除slice內的元素

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5, 6, 7, 8}
    s = append(s[:3], s[4:]...)    // remove 3rd elem
    fmt.Println(s)
}

上面的例子就是展示如何刪除位於第三個位置的元素。最後在介紹如何更新容器內的元素。

package main

import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5, 6, 7, 8}
    s[3] = 10    // [1 2 3 10 5 6 7 8]
    fmt.Println(s)
}

上面的例子就是將第三個位置的元素換成10。slice到這裡告一段落,接下來要開始說明另外一種容器map

map

所謂的map就是以key來當索引儲存value的一種容器接下來看看下列宣告的方式

package main

import "fmt"

func main() {
    m := map[string]int{
        "Bell Labs": 1,
        "Google": 2,
    }
    fmt.Println(m)
}

上面例子就是宣告一個key為字串型態而儲存的value為整數的容器,例子中直接賦值給該容器,如果要新增或更改值的話就如下列所示

package main

import "fmt"

func main() {
    m := map[string]int{
        "Bell Labs": 1,
        "Google": 2,
    }
    m["Apple"] = 3
    m["Google"] = 4
    fmt.Println(m)
}

上面例子多加一個key為Applevalue為3的資料到容器中,並修改Google的value,在介紹完更新與新增後要說明如何刪除容器中的某個key的元素

package main

import "fmt"

func main() {
    m := map[string]int{
        "Bell Labs": 1,
        "Google": 2,
    }
    m["Apple"] = 3
    m["Google"] = 4
    fmt.Println(m)
    delete(m, "Apple")
    fmt.Println(m)
}

這裡使用delete這個方法,透過mapdelete可以刪除key為我們指定的Apple的元素。

結論

這篇介紹 go 的容器的類別,並說明如何使用及宣告,希望對大家的程式撰寫有很大的幫助,接下來再說明方法相關內容之前要先說明 go 的邏輯判斷的寫法。