面向对象:go语言仅支持封装不支持继承和多态
所以go语言没有class,只有struct(结构体)
无论地址还是结构本身,一律用 . 来访问成员
go语言编译器可以自动区分是值传递还是指针传递,值传递不会改变原值,指针传递会复制指针地址
要改变内容必须使用指针接收者,结构过大也考虑用指针接收者,如果有指针接收者,最好用指针接收者
使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针:var t *T = new(T)
,如果需要可以把这条语句放在不同的行(比如定义是包范围的,但是分配却没有必要在开始就做)。
var t *T
t = new(T)
写这条语句的惯用方法是:t := new(T)
,变量 t
是一个指向 T
的指针,此时结构体字段的值是它们所属类型的零值。
package main import "fmt" type struct1 struct { i1 int f1 float32 str string } func main() { ms := new(struct1) ms.i1 = 10 ms.f1 = 15.5 ms.str= "Chris" fmt.Printf("The int is: %d ", ms.i1) fmt.Printf("The float is: %f ", ms.f1) fmt.Printf("The string is: %s ", ms.str) fmt.Println(ms) }
package main import "fmt" //结构体,相当于对象,实体 type TreeNode struct { value int left,right * TreeNode } //(node TreeNode)相当于其他语言的this,表示print()是给node接收的 func (node TreeNode) print(){ fmt.Print(node.value," ") } func (node *TreeNode) traverse(){ if node == nil{ return } node.left.traverse() node.print() node.right.traverse() } func (node *TreeNode) setValue(value int){ if node == nil{ fmt.Println("Setting nil value") return } node.value = value } //使用工厂函数来构造结构体 func createNode(value int) *TreeNode{ return &TreeNode{value:value} } func main() { var root TreeNode fmt.Println(root) root = TreeNode{value:3 } root.left = &TreeNode{} root.right = &TreeNode{5,nil,nil} root.right.left = new(TreeNode) root.left.right = createNode(2) fmt.Println(root) root.traverse() //nodes :=[]TreeNode{ // {value:5}, // {}, // {6,nil,&root}, //} //fmt.Println(nodes) //root.print() //root.right.left.setValue(8) //root.right.left.print() //fmt.Println() // //root.print() //root.setValue(100) //root.print() // //var pRoot *TreeNode //pRoot.setValue(120) //pRoot =&root //pRoot.setValue(220) //pRoot.print() //root.print() }
使用工厂方法创建结构体实例
type File struct { fd int // 文件描述符 name string // 文件名 }
下面是这个结构体类型对应的工厂方法,它返回一个指向结构体实例的指针:
func NewFile(fd int, name string) *File { if fd < 0 { return nil } return &File{fd, name} }
然后这样调用它:
f := NewFile(10, "./test.txt")