(7-5)结构体和共用体:实现共用体

7.5  实现共用体

共用体类型是指将不同的数据项组织成一个整体,它们在内存中占用同一段存储单元。注意,也有的参考书称共用体为“联合”。Go 语言虽然没有直接支持共用体的语法,但可以使用结构体类型嵌入interface{} 类型来模拟共用体的功能。这种方法虽然有些麻烦,但可以实现多种不同类型的数据存储和操作,并提供更大的灵活性和可扩展性。

7.5.1  声明共用体

在Go语言中,用关键字union来标识共用体类型,声明共用体的语法可以通过结构体类型嵌入 interface{} 类型来实现。具体语法格式如下。

type Union struct {
    dataType int // 共用体中数据类型的标识符
    data     interface{}
}

在上述格式中,定义了一个名为 Union 的结构体类型,其中包含一个名为 dataType 的整数和一个名为 data 的 interface{} 类型字段。其中,dataType 字段用于标识共用体中存储的数据类型,例如 0 表示整数、1 表示浮点数等;data 字段则使用 interface{} 类型来存储具有不同类型的值。

需要注意的是,在使用共用体时,必须根据 dataType 字段的值来正确地转换 data 字段中存储的值,并确保其类型正确。在上述示例中,我们使用了 interface{} 类型来存储具有不同类型的值,以便我们可以将其作为参数传递给其他函数进行处理。

7.5.2  创建共用体变量

在 Go 语言中,由于没有直接支持共用体的语法,因此创建共用体变量的方法可以通过结构体类型嵌入 interface{} 类型来实现,然后使用相应的数据类型来初始化 data 字段。例如下面是一段演示代码:

type Union struct {
    dataType int // 共用体中数据类型的标识符
    data     interface{}
}

func main() {
    u1 := Union{dataType: 0, data: int32(42)} // 存储整数类型
    u2 := Union{dataType: 1, data: float32(3.14)} // 存储浮点数类型
    u3 := Union{dataType: 2, data: true} // 存储布尔类型

    fmt.Println(u1)
    fmt.Println(u2)
    fmt.Println(u3)
}

在上述中,首先定义了一个名为 Union 的结构体类型,其中包含一个名为 dataType 的整数和一个名为 data 的 interface{} 类型字段。在主函数main()中,分别创建了三个不同类型的 Union 变量,并将相应的类型变量赋值给它们的 data 字段。在实现变量初始化工作时,需要根据字段dataType来选择正确的数据类型,并使用相应的数据类型来初始化 data 字段。最后,调用函数fmt.Println()来输出每个 Union 变量的内容到控制台。输出结果如下:

{0 42}
{1 3.14}
{2 true}

由此可以看到,通过将不同类型的值存储在同一个 Union 变量中,成功地实现了共用体的功能,并实现了多种不同类型的数据存储和操作。

实例7-9:存储和操作多种不同类型的几何图形(源码路径:Go-codes\7\tu.go

实例文件tu.go的具体实现代码如下所示。

type ShapeType int

const (
    Circle ShapeType = iota
    Rectangle
)

type ShapeData struct {
    shapeType ShapeType // 图形类型标识符
    data      interface{}
}

type CircleData struct {
    x, y  float64
    radius float64
}

type RectangleData struct {
    x1, y1, x2, y2 float64
}

func (d ShapeData) Print() {
    switch d.shapeType {
    case Circle:
        c := d.data.(CircleData)
        fmt.Printf("Circle: center=(%f,%f), radius=%f\n", c.x, c.y, c.radius)
    case Rectangle:
        r := d.data.(RectangleData)
        fmt.Printf("Rectangle: (%f,%f)-(%f,%f)\n", r.x1, r.y1, r.x2, r.y2)
    }
}

func main() {
    cdata := CircleData{x: 0, y: 0, radius: 5}
    s1 := ShapeData{shapeType: Circle, data: cdata}

    rdata := RectangleData{x1: -1, y1: -1, x2: 1, y2: 1}
    s2 := ShapeData{shapeType: Rectangle, data: rdata}

    s1.Print()
    s2.Print()
}

对上述代码的具体说明如下:

  1. 首先定义了一个名为 ShapeType 的枚举类型,表示几何图形的类型;
  2. 然后,定义了一个名为 ShapeData 的结构体类型,其中包含一个名为 shapeType 的整数和一个名为 data 的 interface{} 类型字段。
  3. 接下来,定义了两个具体图形的数据类型:CircleData 和 RectangleData,分别表示圆和矩形。在 方法Print()中,根据 shapeType 字段的值将 data 字段中存储的值转换为实际类型,并输出相应的图形信息到控制台。
  4. 在主函数main()中,创建了两个不同类型的 ShapeData 变量,并将相应的具体图形数据变量赋值给它们的 data 字段。最后,调用每个 ShapeData 变量的 Print() 方法,输出其中存储的图形信息。

执行后会输出:

Circle: center=(0.000000,0.000000), radius=5.000000
Rectangle: (-1.000000,-1.000000)-(1.000000,1.000000)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值