1. 程式人生 > >go的靜態型別和動態型別

go的靜態型別和動態型別

      先來看個簡單的go程式:

package main

import (
	"fmt"
)

type TaskIntf interface {
	Process()
}
 
type Task struct {
	TaskId  string
	X int 
	Y int
}

func (p *Task)Process() {
	fmt.Printf("%+v\n", p)
}


func main() {
	var t TaskIntf = new(Task)
	fmt.Printf("%T\n", t)
	t.Process()
	fmt.Printf("%+v\n", t)
}

       結果:

*main.Task
&{TaskId: X:0 Y:0}
&{TaskId: X:0 Y:0}

       

       再看:

package main

import (
	"fmt"
)

type TaskIntf interface {
	Process()
}
 
type Task struct {
	TaskId  string
	X int 
	Y int
}

func (p *Task)Process() {
	fmt.Printf("%+v\n", p)
}


func main() {
	var t TaskIntf = new(Task)
	fmt.Printf("%T\n", t)

	t.X = 1

	t.Process()
	fmt.Printf("%+v\n", t)
}

         結果出現編譯錯誤:t.X undefined (type TaskIntf has no field or method X)

 

        注意到, 對於t而言,靜態型別是TaskIntf,  動態型別(執行時)是Task.  而在t.X = 1時,編譯器會進行靜態檢查, 故編譯錯誤。 那怎麼辦呢? 可以這麼搞:

package main

import (
	"fmt"
	"encoding/json"
)

type TaskIntf interface {
	Process()
}
 
type Task struct {
	TaskId  string
	X int 
	Y int
}

func (p *Task)Process() {
	fmt.Printf("%+v\n", p)
}


func main() {
	var t TaskIntf = new(Task)
	fmt.Printf("%T\n", t)

	str_json := `{"taskid":"xxxxxx", "x":1, "y":2}`
	json.Unmarshal([]byte(str_json), t)

	t.Process()
	fmt.Printf("%+v\n", t)
}

        結果:

*main.Task
&{TaskId:xxxxxx X:1 Y:2}
&{TaskId:xxxxxx X:1 Y:2}

        順便提一句, 在Task中, 變數的首字母要大寫, 否則呵呵噠。

        

       還可以這麼搞:

package main

import (
	"fmt"
)

type TaskIntf interface {
	Process()
	GetTask() *Task
}
 
type Task struct {
	TaskId  string
	X int 
	Y int
}

func (p *Task)Process() {
	fmt.Printf("%+v\n", p)
}

func (p *Task)GetTask() *Task {
	return p
}

func main() {
	var t TaskIntf = new(Task)
	fmt.Printf("%T\n", t)

	t.GetTask().TaskId = "xxxxxx"
	t.GetTask().X = 1
	t.GetTask().Y = 2

	t.Process()
	fmt.Printf("%+v\n", t)
}

        結果:

*main.Task
&{TaskId:xxxxxx X:1 Y:2}
&{TaskId:xxxxxx X:1 Y:2}

 

        不多說。