• 结构体/接口


    一.struct(结构体)

    go中的struct可以实现oop中的类、方法

    1.创建

    type S1 struct {
    	Name string //成员
    	Age  int //成员
         Interfaceer //interface
         Structer // struct }

      

    2.声明

    var s S1
    var s *S1
    s := new(S1)
    

      

    3.初始化

    s = S1{Name: "go", Age: 2} // 或者 S1{"go", 2}
    s = &S1{Name: "go", Age: 2}
    

      

    4.方法:

    go语言中的oop很另类,类在go里面叫做receiver,receiver可以是除了interface之外的任何类型。方法和类并非组织在一起,传统的oop方法和类放在一个文件里面,而go语言只要在同一个包里就可,可分散在不同文件里。go的理念就是数据和实现分离.

    定义:

    func (recv receiver_type) methodName(parameter_list) (return_value_list) { … }
    func (_ receiver_type) methodName(parameter_list) (return_value_list) { … }
    func (this receiver_type) methodName(parameter_list) (return_value_list) { … }
    func (self receiver_type) methodName(parameter_list) (return_value_list) { … }
    

      

    reciever最好定义成指针的形式,因为方法中可能对成员有更改操作.


    示例代码:

    type S1 struct {
    	Name string
    	Age  int
    }
    
    func (s1 *S1) ChangeName(name string) {
    	s1.Name = name
    }
    
    func main() {
    	s := &S1{Name: "go", Age: 2}
    	s.ChangeName("golang")
    	fmt.Println(s.Name)
    }
    

      

    5.相当另类的构造方法:

    type S1 struct {
    	Name string
    	Age  int
    }
    
    // 实现了一个构造方法
    func NewS1(n string, a int) *S1 {
    	return &S1{n, a}
    }
    
    func main() {
    	s := NewS1("go", 1)
    	fmt.Println(s.Name)
    }
    

      

    6.匿名域(类似继承)

    type Info struct {
    	From   string
    	ResNum int
    }
    
    type S1 struct {
    	Name string
    	Age  int
    	Info //这是一个匿名域
    }
    
    func main() {
    	s := new(S1)
    	s.From = "google" // From在struct唯一,所以可以直接访问
    	s.ResNum = 1000	  // ResNum在struct唯一,所以可以直接访问
    	fmt.Println(s)
    }
    

      

    二.接口

    Go语言中的接口是一些方法的集合(method set),它指定了对象的行为:如果它(任何数据类型)可以做这些事情,那么它就可以在这里使用.
    Go语言中一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口.

    1.定义

    type Namer interface {
        Method1(param_list) return_type
        Method2(param_list) return_type
    }
    

      

    2.接口赋值
    (1).通过struct实例赋值
    要求对象实现了接口的所有方法

    type Selecter interface {
    	Read() int
    }
    
    type File struct {
    	file string
    }
    
    func (f *File) Read() int {
    	return len(f.file)
    }
    
    func main() {
    	file := File{file: "a.txt"} // 创建一个File实例
    	selecter := file // 将实例赋值给接口
    	fmt.Println(selecter.Read())
    }
    

      

    也可以这样:

    file := new(File)
    file.file = "a.txt"
    selecter := file // 将一个指针赋值给接口
    fmt.Println(selecter.Read())
    
    // 也可以这样
    file := Selecter(File)
    

      

    (2).将接口赋值给另一个接口
    假设接口A中定义的所有方法,都在接口B中有定义,那么B接口的实例可以赋值给A的对象。反之不成立.也就是B要包含A,就可以将B接口实例赋值给A

    type Selecter interface {
    	Read() int
    }
    
    type Selecter2 interface {
    	Read() int
    	Write() int
    }
    
    type File struct {
    	file string
    }
    
    func (f *File) Read() int {
    	return len(f.file)
    }
    
    func (f *File) Write() int {
    	return len(f.file)
    }
    
    func main() {
    	var selecter2 Selecter2 = &File{file: "a.txt"}
    	var selecter Selecter = selecter2 //Selecter中的方法都在Selecter2中,所以可以将Selecter2的实例赋值给Selecter
    	fmt.Println(selecter.Read())
    }
    

      

    3.接口嵌套

    type Selecter2 interface {
    	Selecter
    	Write() int
    }
    
    //等同于:
    type Selecter2 interface {
    	Read() int
    	Write() int
    }
    

    4.空接口
    空接口比较特殊,它不包含任何方法
    在Go语言中,所有其它数据类型都实现了空接口。

    t := []int{1, 2, 3, 4}
    	s := make([]interface{}, len(t)) //int也实现了空接口,所以可以用interface{}来代替
    	for i, v := range t {
    		s[i] = v
    	}
    	fmt.Println(s)
    

      

    5.接口查询
    检查对象是否实现了某个接口

    type Reader interface {
    	Read() int
    }
    
    type Writer interface {
    	Write() int
    }
    
    type File struct {
    	filename string
    }
    
    func (f *File) Read() int {
    	return len(f.filename)
    }
    
    func main() {
    	var reader Reader = new(File)
    	if v, ok := reader.(Writer); ok { // 检查是否实现了Writer接口
    		fmt.Println(v, "reader 实现了Writer接口")
    	}
    }
    

      

    6.类型查询:
    在Go语言中,我们可以使用type switch语句查询接口指向的对象实例的类型.一般是和接口查询配合使用.

    import (
    	"fmt"
    )
    
    type Reader interface {
    	Read() int
    }
    
    type File struct {
    	filename string
    }
    
    func (f File) Read() int {
    	return len(f.filename)
    }
    
    func main() {
    	var reader Reader = File{filename: "a.txt"}
    	switch v := reader.(type) {  // reader必须是一个接口类型
    	case File: // v类型是File
    		fmt.Println("File", v)
    	}
    }
    

      

    关于golang的结构体与接口:
    结构体定义了属性,接口定义了方法.两者松耦合.举个例子:会英语要会读会写(要实现Read和Write两个方法的接口),如果一个学生(struct,包含学号,姓名等),实现了会读会写,那么就可以说这个学生会英语.如果一个老师(struct,包含学号,姓名等),实现了会读会写,我们就说这个老师会英语.

    Duck Type:当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
    我们并不关心对象是什么类型,到底是不是鸭子,只关心行为.

    7.类型断言
    接口类型向普通类型的转换称为类型断言(运行期确定);
    value, b := interface.(Type),value 是 Type 的默认实例;b 是 bool 类型,表明断言是否成立

    func main() {
    	var arr []int
    	if b, ok := interface{}(arr).(int); ok { // arr赋值给空接口,判断是否是int类型
    		fmt.Println(b)
    	} else {
    		fmt.Println("not int array")
    	}
    }
    

      

    三.关于继承

    1.属性继承

    type Father struct {
    	Name string
    }
    
    type Son struct {
    	Father
    	age int
    }
    
    func main() {
    	son := Son{Father{"son"}, 10} // 初始化Father
    	fmt.Println(son.Father.Name)
    }
    

      

    2.方法继承(这个举例不是很妥当)

    type Say interface {
    	SayName()
    	SayAag()
    }
    
    type Son struct {
    	name string
    	Say
    }
    
    func (this *Son) SayName() {
    	fmt.Println(this.name)
    }
    
    func main() {
    	son := new(Son)
    	son.name = "Son"
    	son.SayName()
    }
    

      

    3.多重继承

    // Father
    type Father struct { 
    	Book string
    }
    
    func (this *Father) Say() {
    	fmt.Println("hello world")
    }
    
    func (this *Father) Read() {
    	fmt.Println(this.Book)
    }
    
    // Monther
    type Monther struct {
    	Age int
    }
    
    func (this *Monther) Say() {
    	fmt.Println("hello world")
    }
    
    // 继承Father和Monther, 并添加一个属性
    type Son struct {
    	xuehao int
    	Father
    	Monther
    }
    
    func main() {
    	son := new(Son)
    	son.xuehao = 150
    	son.Book = "<rolling>"
    	son.Age = 15
    	son.Read()
    	//son.Say() // 出错,因为Father和Monther都有Say方法,产生混淆
    	son.Father.Say()
    }
    

      

  • 相关阅读:
    HDU 1507 Uncle Tom's Inherited Land*
    HDU 2527 Safe Or Unsafe (哈夫曼树)
    HDU More lumber is required
    HDU Machine Schedule
    HDU 3709 Balanced Number (数位DP)
    HDU Number Sequence (容斥原理)
    csharp: word or excel Convert to PDF
    csharp: winform using Microsoft.Ink(Tablet PC API) create Signature image
    Create Ms Word doc using Javascript And vbscript
    sql distinct
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7638818.html
Copyright © 2020-2023  润新知