1. 程式人生 > >Go語言學習筆記----與C語言的比較學習

Go語言學習筆記----與C語言的比較學習

最近學習了golang(go語言),其中大部分是和C相似的,記錄一下不同的地方,需要注意

1.go的左花括號“{”不能單獨放在一行
出錯程式碼:

package main
import "fmt"
func main()  
{ //error, can't have the opening brace on a separate line
    fmt.Println("hello there!")
}

錯誤資訊:
/tmp/sandbox826898458/main.go:6: syntax error:
unexpected semicolon or newline before {

分析:
兩個花括號各佔一行,上下對齊,是C語言的一種編碼風格.而另一種風格是左花括號不獨佔一行,而花括號獨佔一行,這也是Go語言遵循的唯一風格

改正程式碼:

package main
import "fmt"
func main() {  
    fmt.Println("works!")
}

2.分支語句if…else…的判斷條件不加括號,並且else不能另起一行

錯誤程式碼

for true {
    fmt.Scanln(&cmd)
    if (strings.Compare(cmd, "help") == 0) {
        fmt.Println("help"
) } else if (strings.Compare(cmd, "add") == 0) { fmt.Println("add") } else { fmt.Println("Wrong cmd!") } }

c語言的if判斷條件是要加括號()的,而go語言不需要.
另外注意else語句必須緊跟著上一個if的結束花括號,不能另起一行.
改正程式碼:

for true {
    fmt.Scanln(&cmd)
    if strings.Compare(cmd, "help") == 0 {
        fmt.Println
("help") } else if strings.Compare(cmd, "add") == 0 { //注意else不能另起一行 fmt.Println("add") } else { //注意else不能另起一行 fmt.Println("Wrong cmd!") } }

3.每句末尾不加分號;
在 Go 程式中,一行代表一個語句結束。每個語句不需要像 C 家族中的其它語言一樣以分號 ; 結尾,因為這些工作都將由 Go 編譯器自動完成。
如果你打算將多個語句寫在同一行,它們則必須使用 ; 人為區分,但在實際開發中我們並不鼓勵這種做法。

4.C中的NULL,在go中為nil
C常用NULL表示空指標,在go中將空指標賦值為nil

6.判斷字串string是否為空

if len(str) == 0{

}

if str == "" {

}

兩個效率是一樣的

7.函式指標
C中函式指標:

typedef struct DataNode //先定義結構體
{
    char* cmd;
    char* desc;
    int (*handler)();//函式指標
    struct DataNode *next;
}tDataNode;

呼叫方法:

tDataNode *p    //假設p指向一個非空tDataNode
p->handler();   //用這個tDataNode中的函式指標呼叫響應函式

go語言:

type DataNode struct {  //先定義結構體
    cmd     string
    desc    string
    handler func()    //函式指標,指向一個沒有返回值的函式
    handler func() int //函式指標,指向一個返回值int的函式
    next    *DataNode
}

呼叫方法:

var p *DataNode
p.handler()

注意go中指標的使用方式,在下一點中詳述

8.指標呼叫方式:

type DataNode struct {
    cmd     string
    desc    string
    handler func()
    next    *DataNode
}
var p *DataNode //假設p指標指向一個非空的DataNode結構體
p.cmd   //訪問cmd域(是個字串)
p.desc  //訪問desc域(是個字串)
p.handler() //呼叫handler域(是個函式指標)
p.next  //訪問next域(是個DataNode指標)

9.函式呼叫順序
報錯:

.\menu_v2.5.go:37: syntax error: unexpected findCmd, expecting (

main函式中呼叫findCmd函式,則findCmd函式的定義必須放在main之前.這與c語言類似

10.型別強制轉換

c語言用”(型別)”的語法進行強制轉換,如

main()
{
    float f=5.75;
    printf("(int)f=%d,f=%f/n",(int)f,f);
} 

將float f強制轉換成int f float f=5.75;printf(“(int)f=%d,f=%f/n”,(int)f,f); 本例表明,f雖強制轉為int型,但只在運算中起作用, 是臨時的,而f本身的型別並不改變。因此,(int)f的值為 5(刪去了小數)而f的值仍為5.75。

而go語言不支援這種語法,必須用unsafe包:

package main

import (
    "fmt"
    "unsafe"
)
func main() {
    var n int64 = 5
    var pn = &n
    var pf = (*float64)(unsafe.Pointer(pn))
    // now, pn and pf are pointing at the same memory address
    fmt.Println(*pf) // 2.5e-323
    *pf = 3.14159
    fmt.Println(n) // 4614256650576692846
}

注意這一句:

var pf = (*float64)(unsafe.Pointer(pn))

是兩個操作:先將指向int64型別的指標pn用unsafe.Pointer()轉換成unsafe.Pointer指標(無型別,相當於c的void指標,下一節說明),再將無型別指標強制轉換成float64型別指標

11.無型別指標unsafe.Pointer
go語言的unsafe.Pointer型別指標(對應C語言的void指標,go裡面沒有void指標)
舉例:

void *args  //C語言宣告void型指標args
args unsafe.Pointer   //go語言宣告unsafe.Pointer型指標args         
                      //這是個特殊指標型別,不用加*
args *int     //go語言宣告int型指標,注意與上面的區別