• go语法-结构体和接口


    看go代码,非常考验对go语言的理解程度。觉得费解的地方,肯定是有不熟悉的语法。

    3,接口与实现

    type Error interface {
    	Error() string
    	Stacktrace() Error
    	Trace(offset int, format string, args ...interface{}) Error
    	Data() interface{}
    }
    type A struct {
      data  interface{}
      msgtraces []msgtraceItem
      stacktrace []uintptr
    }
    function newA(data interface{}) {
      return &A{
        data:  data
        msgtraces: nil
        stacktrace: nil
      }
    }
    
    func (a A) Error() string {
      return fmt.Sprintf("#{err}");
    }
    
    func (a A) Stacktrace() Error {
      return a; // 因为a是实现Error接口的结构体的实例
    }
    
    func (a A) Trace() Error {
      return a;
    }
    
    func (a A) Data() interface{} {
      return a.data;
    }
    

      

    3,接口

    Go 语言的接口设计是非侵入式的,接口编写者无须知道接口被哪些类型实现。而接口实现者只需知道实现的是什么样子的接口,但无须指明实现哪一个接口。编译器知道最终编译时使用哪个类型实现哪个接口,或者接口应该由谁来实现。

    a := PhoneConnecter{"PhoneConnecter"}
    a.Connect()
    Disconnect(a)

    func Disconnect(usb USB) {
        if pc, ok := usb.(PhoneConnecter); ok {
            fmt.Println("Disconnect", pc.name)
            return
        }
        fmt.Println("Unknown device")
    }
    // 改造为空接口
    func Disconnect(usb interface{}) {
        switch v := usb.(type)
        case PhoneConnecter
            fmt.Println("Disconnect", v.name)
        defult:
            fmt.Println("Unknown device")
    }

    接口转换可以降级。

    比如 type struct TVConnect {

      name string

    }

    是不能强制转换为USB,因为没有实现USB。

    1,结构体

    结构体是不同数据类型的集合,聚合数据类型。数组是相同数据类型的集合。

    go中没有类,继承,只保留了结构体及组合。

    初始化的5种方法:

    type struct Person {

      name string

      age int

      sex string

      address string

    }

    方法1:

    var p1 Person

    p2.name = ""

    fmt.Printf(p2);

    方法2:

    p3: = Person{}

    p3.name = ""

    fmt.Printf(p3);

    方法3://常用

    p4: = Person{

      name: xx

    }

    fmt.Printf(p4);

    方法4:

    p5 := Person{"", } // 顺序不能写错

    方法5:New // 指针类型

    p1 := Person{"1", }

    p2 := p1 // 深拷贝

    p2.name = "2"

    //结论是p1, p2两个空间。修改的时候两个互不干预。

    var pp1 * Person

    pp1 = &p1 // 浅拷贝

    fmt.PrintLn(*pp1)

    pp1.name = "3"

    fmt.PrintLn(pp1) // &{}

    fmt.PrintLn(p1) // {}

    pp2 := new(Person) //指针类型

    // (*pp2).name

    pp2.name // 简写

    结构体的指针

    值类型:int,float,bool,string,array,struct

    引用类型:slice,map,function,pointer

    但常用指针: new (),不是nil,空指针,指向了新分配的类型的内存空间,里面存储的零值。

    结构体是值类型:

    p1 := Person{name:"", age:"", sex:"", address:"北京市"}

    p2 := p1

    p1.name = "newName"

    p1变了,但p2没变。

    默认是深copy,如果想浅copy,定义指针。

    pp1 := &p1

    pp1.name = "王五"; //这样原始数据p1就被修改了。

    内置的pp2:=new(Person)

    结构体是值类型,往往借助于指针来操作(通过new),new之后并不是nil,而是开辟了一段内存空间,存储零值。

    newStruct是构造函数

    结构体嵌套

    package main
    import "fmt"
    type A struct {
        ax, ay int
    }
    type B struct {
        A
        bx, by float32
    }
    func main() {
        b := B{A{1, 2}, 3.0, 4.0}
        fmt.Println(b.ax, b.ay, b.bx, b.by) // 嵌入结构体的成员,可以通过外部结构体的实例直接访问。
        fmt.Println(b.A)
    }

     匿名结构体,匿名字段(一个结构体的字段没有字段名)

    匿名结构体类比匿名函数,平常不常用。

     s2:= struct {

    name string

    age int

    } {

    name:"李四"

    age:"19"

    }

    匿名结构体字段

    type Worker struct {

    string

    int

    }

    w2:=Work{"li", 32}

    w2.string

    w2.int

    匿名字段类型不能重复,否则冲突。

    还可以把另一个结构体作为匿名字段。

    结构体嵌套

    最初始的理解是对的。

    type Book struct {

    bookName string

    price float64

    }

    type Student struct {

    name string

    age int

    book Book

    }

    b1 := Book{}

    b1.bookName = "西游记"

    b1.price = 45.8

    s1 := Student{}

    s1.name = ""

    s1.age = 

    s1.book = b1;

    s1.book.bookName

    s1.book.price

    也可以

    s2:=Student{name:"", age: 19, book: Book{bookName:"", price:89.,7}}

    实际结构体的嵌套需要定义指针,而不是值复制。

    book :=  Book{bookName:"", price:89.,7}

    s2:=Student{name:"", age: 19, book: &book}

    go中的面向对象

    用结构体嵌套来实现类的继承。

    提升字段:子结构体是匿名字段的时候。可以直接使用子结构体的字段,不需要多点一次子结构体的名字。

    注:代码里非常常用。

    总结:嵌套分为两种情况:一种是模拟继承,is a子类是特殊的父类。可以直接访问子类的字段。

    k另一种情况是:模拟面向对象的聚合关系,has a,一个类拥有另一个类。不能直接访问子类的字段。

  • 相关阅读:
    bzoj2301: [HAOI2011]Problem b懵逼乌斯反演
    bzoj3504: [Cqoi2014]危桥 网络流
    bzoj1588: [HNOI2002]营业额统计 splay瞎写
    bzoj1008快速面
    洛谷1212手动枚举各种情况(缩代码成瘾)
    bzoj1968真·想sha法bi题
    bzoj3674同上(好短)
    bzoj3673可持久化线段树实现可持久化数组实现可持久化并查集(好长)
    uoj98未来程序改 纯暴力不要想了
    bzoj3680模拟退火
  • 原文地址:https://www.cnblogs.com/zccst/p/13970929.html
Copyright © 2020-2023  润新知