Feeds:
文章
留言

Archive for 八月 22nd, 2012

心血來潮玩 Go v1.0.2

上次玩 Go 已經是 2010/1/20 “Windows 編寫 Go 語言初體驗"

最近心血來潮看到別人介紹 Go,雖然目前這個語言還熱不起來

不過有人推薦玩 Python 的應該來試試看 Go,於是我又在重新入門一次

目前 Go v1.0.2 版本對 Windows 上開發已經簡單許多,預設安裝 c:\Go 目錄結構如下

/api
/bin
    - go.exe   ; 編譯器
    - godoc.exe
    - gofmt.exe
/doc
/example    ; 我的測試程式
    - hello.go
    /cwc
         - ext.go
/include
/lib
/misc
/pkg
    /obj
    /tool
    /windows_386 ; 套件目錄
/src
/test

本次測試 Go 的基本語法,基本上還蠻簡潔一致,寫一般程式程式沒什麼問題
另外有一個很重要的特點是 go.exe run 可將 go 程式編譯並執行
也就是說可以將 go 當作簡單的直譯器(實際上他編的很快)來使用 

執行本篇文章的範例,只需要在 example 目錄下執行
../bin/go.exe run hello.go

結果如下
======================================== ext.go

package cwc

func Add(a int,b int) int {
return a+b
}

========================================
hello.go
/* hello.go */

// 單行註解
/**
 * 多行註解
 */
package main  // 套件名稱

import fmt "fmt"  // 引用套件
// 引入多個套件
import (
    "os"
    "os/exec"
    "io/ioutil"
    "./cwc"   // 自訂模組
)

// 型別別名
type ByteSize float64
// 常數定義
const (
    _           = iota // ignore first value by assigning to blank identifier
    KB ByteSize = 1 << (10 * iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)
// 變數同時初始化
var (                   // 小括號必要
    VAR_1 = 1           // 結尾不需要加逗號,分號
    VAR_2 = "string"    // 不需加型別
)

// 函數定義
func sayHello() {
    // 標準輸出
    fmt.Printf("Hello, world; or Καλημέρα κόσμε; or こんにちは 世界\n")
}

func numAdd(a int,b int)(int){
    return a+b
}

func returnMore() (int, string){
    return 99, "Chui-Wen Chiu"
}

func arrayArg(intArr *[3]int)(int){
    return len(intArr)
}

/*
 * 回傳參數指定名稱,程式中可直接用該名稱賦值
 */
func namedResultParam() (code int, name string){
    code = 99
    name = "Chui-Wen Chiu"
    return // 必要
}

// Person class 
type Person struct{
    name string
    age  int
    title  string
}

func (self Person) toString() string{
    return fmt.Sprintf("%s@%d@%s", self.name, self.age, self.title)
}

// 真的會修改物件值
func (self *Person) setName(name string) {
    self.name = name
}

func (self Person) setName2(name string) {
    self.name = name
}

// IJob interface
type IJob interface{
    Doit(name string, data int)
}

func doJob(job IJob) bool {
    job.Doit("aaaa", 1)

    return true
}

type IAny interface{
}

func doAny(data IAny) bool{

    return true
}

type BasicJob struct{

}

func (self *BasicJob) Doit(name string, data int) {
    fmt.Println("Doit")
}

//
func FileCopy(src string, dst string){
    source, err := ioutil.ReadFile("go.exe")
    if err != nil {
        fmt.Println(err)
    }else{                
        ioutil.WriteFile("go.exe.bak", source, 0777)
    }
}

func ProcStdIn() {
    // 從 pipe 取得標準輸入資料, ex: echo "hello stdin" | go run hello.go
    datas, err := ioutil.ReadAll( os.Stdin )
    if err != nil{

    }else{
        fmt.Println( string(datas))
    }
}

func ProcCmdLineArgs() {
    // 取得命令列參數, ex: go run hello.go 1 2 3
    fmt.Println( os.Args )
}

// 程式進入點
func main() {    
    sayHello()
    fmt.Println( numAdd(3,4) )

    // -- func --
    // 取值並隱式決定型別
    a,b := returnMore()
    fmt.Printf("%d = %s\n", a,b)

    c,d := namedResultParam()
    fmt.Printf("%d = %s\n", c,d)    

    fmt.Println( arrayArg( &[...]int{1,2,3} ) )
    fmt.Println( arrayArg( &[3]int{1,2,3} ) )

    // -- for --
    for i:=0;i<5;i++ {         fmt.Println(i)             }          for k:= range "1234"{         fmt.Println(k)             }          // 字串迭代字元     for k2,v2:= range "1234"{         fmt.Printf("%d => %c\n", k2, v2)        
    }    

    // 平行多個賦值
    // 陣列反轉
    fmt.Println("== [1,2,3,4] Reverse test ==");
    arr := [...]int{1,2,3,4}
    for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {         arr[i], arr[j] = arr[j], arr[i]     }              for k3,v3:=range arr {         fmt.Printf("%d => %d\n", k3, v3)        
    }    

    if true {
        fmt.Println("If statement Test")               
    }

    // switch statement test
    for _,v3 := range "123456#"{
        switch(v3){
            case '2', '4', '6':
                fmt.Printf("%c => even\n", v3)
            case '1', '3', '5':
                fmt.Printf("%c => odd\n", v3)
            default:
                fmt.Printf("%c => unknown\n", v3)
        }
    }

    // 多重判斷式
    switch {
        case len(arr)>3:
            fmt.Println("gt 3")
        case len(arr)==3:
            fmt.Println("eq 3")
        case len(arr) %d\n", mapData_k, mapData[mapData_k]);
    }

    // map check & delete
    // 假如 Key=Arick 存在則刪除
    if _, ok :=mapData["Arick"]; ok{
        delete(mapData, "Arick")
    }
    if _, ok :=mapData["Arick"]; !ok{
        fmt.Println("kill Key=Arick element Success");       
    }   

    person := Person{
        name: "Chui-Wen Chiu",
        age: 32,
        title: "programmer",
    }
    fmt.Println( person.toString() )

    person2 := Person{
        name: "Arick",
        age: 32,
        title: "programmer",
    }
    fmt.Println( person2.toString() )    

    person2.setName2("xxxxx")
    fmt.Println( person2.toString() )    
    person2.setName("yyyyy")
    fmt.Println( person2.toString() )    

    doJob( &BasicJob{} )

    // 使用自訂模組
    fmt.Println( cwc.Add(100, 200) )

}

func runExternalCommand(){
    cmd_output, err := exec.Command("ipconfig", "/all").Output()    
    if err != nil {
        fmt.Println(err)
    }    
    fmt.Println(string(cmd_output))
}

Read Full Post »