GO42

作者: 一斗 | 来源:发表于2019-12-03 09:51 被阅读0次

1. 自定义类型和类型别名

自定义类型

type IZ int

这里IZ就是完全是一种新类型,然后我们可以使用下面的方式声明变量:

var a IZ = 5
  • 类型转换时必须显式转换
  • 不会拥有原基础类型所附带的方法
package main

import (
    "fmt"
)

type A struct {
    Face int
}
type Aa A // 自定义新类型Aa,没有基础类型A的方法

func (a A) f() {
    fmt.Println("hi ", a.Face)
}

func main() {
    var s A = A{ Face: 9 }
    s.f()

    var sa Aa = Aa{ Face: 9 }
    sa.f()
}
编译错误信息:sa.f undefined (type Aa has no field or method f)

类型别名

type IZ = int 

这种写法其实是定义了int类型的别名,类型别名在1.9中实现,可将别名类型和原类型这两个类型视为完全一致使用。

  • 类型之间无需转换
  • 拥有原基础类型所附带的方法

2. 结构体是值类型,可以使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针。表达式 new(Type) 和 &Type{} 是等价的。&struct1{a, b, c} 是一种简写,底层仍然会调用 new ()。

3. 嵌入与聚合

结构体中包含匿名(内嵌)字段叫嵌入或者内嵌;而如果结构体中字段包含了类型名,还有字段名,则是聚合。

type Human struct {
    name string
}

type Person1 struct {           // 内嵌
    Human
}

type Person2 struct {           // 内嵌, 这种内嵌与上面内嵌有差异
    *Human
}

type Person3 struct{             // 聚合
    human Human
}

嵌入在结构体中广泛使用,在Go语言中如果只考虑结构体和接口的嵌入组合方式,一共有下面四种:

  • 1.在接口中嵌入接口:

这里指的是在接口中定义中嵌入接口类型,而不是接口的一个实例,相当于合并了两个接口类型定义的全部函数。下面只有同时实现了Writer和 Reader 的接口,才可以说是实现了Teacher接口,即可以作为Teacher的实例。Teacher接口嵌入了Writer和 Reader 两个接口,在Teacher接口中,Writer和 Reader是两个匿名(内嵌)字段。

type Writer interface{
   Write()
}

type Reader interface{
   Read()
} 

type Teacher interface{
  Reader
  Writer
}
  • 2.在接口中嵌入结构体:

这种方式在Go语言中是不合法的,不能通过编译。

type Human struct {
    name string
}

type Writer interface {
    Write()
}

type Reader interface {
    Read()
}

type Teacher interface {
    Reader
    Writer
    Human
}

存在语法错误,并不具有实际的含义,编译报错:
interface contains embedded non-interface Base

Interface 不能嵌入非interface的类型。
  • 3.在结构体中内嵌接口:

初始化的时候,内嵌接口要用一个实现此接口的结构体赋值;或者定义一个新结构体,可以把新结构体作为receiver,实现接口的方法就实现了接口(先记住这句话,后面在讲述方法时会解释),这个新结构体可作为初始化时实现了内嵌接口的结构体来赋值。

package main

import (
    "fmt"
)

type Writer interface {
    Write()
}

type Author struct {
    name string
    Writer
}

// 定义新结构体,重点是实现接口方法Write()
type Other struct {
    i int
}

func (a Author) Write() {
    fmt.Println(a.name, "  Write.")
}

// 新结构体Other实现接口方法Write(),也就可以初始化时赋值给Writer 接口
func (o Other) Write() {
    fmt.Println(" Other Write.")
}

func main() {

    //  方法一:Other{99}作为Writer 接口赋值
    Ao := Author{"Other", Other{99}}
    Ao.Write()

    // 方法二:简易做法,对接口使用零值,可以完成初始化
    Au := Author{name: "Hawking"}
    Au.Write()
}

程序输出:
Other   Write.
Hawking   Write.
  • 4.在结构体中嵌入结构体:

在结构体嵌入结构体很好理解,但不能嵌入自身值类型,可以嵌入自身的指针类型即递归嵌套。

在初始化时,内嵌结构体也进行赋值;外层结构自动获得内嵌结构体所有定义的字段和实现的方法。

4. channel

Go中通道可以是发送(send)、接收(receive)、同时发送(send)和接收(receive)。

// 定义接收的通道
receive_only := make (<-chan int)
 
// 定义发送的通道
send_only := make (chan<- int)

// 可同时发送接收
send_receive := make (chan int)
  • chan<- 表示数据进入通道,要把数据写进通道,对于调用者就是发送。
  • <-chan 表示数据从通道出来,对于调用者就是得到通道的数据,当然就是接收。

定义只发送或只接收的通道意义不大,一般用于在参数传递中

可以通过内置的close函数来关闭通道实现。

  • 通道不需要经常去关闭,只有当没有任何可发送数据时才去关闭通道;

  • 关闭通道后,无法向通道再发送数据(引发panic 错误后导致接收立即返回零值);

  • 关闭通道后,可以继续向通道接收数据,不能继续发送数据;

  • 对于nil 通道,无论收发都会被阻塞。

相关文章

  • GO42

    1. 自定义类型和类型别名 自定义类型 这里IZ就是完全是一种新类型,然后我们可以使用下面的方式声明变量: 类型转...

网友评论

      本文标题:GO42

      本文链接:https://www.haomeiwen.com/subject/pyzqgctx.html