Go基础_1_46 类型断言

Tutorial: Go初级 Category: Go Published: 2026-04-07 13:58:26 Views: 21 Likes: 0 Comments: 0
package main

import (
    "fmt"
    "math"
)

// 1.定义一个接口
type Shape interface {
    peri() float64 // 形状的周长
    area() float64 // 形状的面积
}

// 2.定义实现类:三角形
type Triangle struct {
    //a float64
    //b float64
    //c float64
    a, b, c float64
}

type Circle struct {
    radius float64
}

func (t Triangle) peri() float64 {
    return t.a + t.b + t.c
}

func (t Triangle) area() float64 {
    p := t.peri() / 2
    s := math.Sqrt(p * (p - t.a) * (p - t.b) * (p - t.c))
    return s
}

func (c Circle) peri() float64 {
    return c.radius * 2 * math.Pi
}

func (c Circle) area() float64 {
    return math.Pow(c.radius, 2) * math.Pi
}

func getType(s Shape) {
    // 断言
    if ins, ok := s.(Triangle); ok {
        fmt.Println("是三角形,三边是:", ins.a, ins.b, ins.c)
    } else if ins, ok := s.(Circle); ok {
        fmt.Println("是圆形,半径是:", ins.radius)
    } else if ins, ok := s.(*Triangle); ok {
        fmt.Printf("ins:%T,%p,%p\n", ins, &ins, ins)
        fmt.Printf("s:%T,%p,%p\n", s, &s, s)
    } else {
        fmt.Println("我也不知道了。。。")

    }
}

func getType2(s Shape) {
    switch ins := s.(type) {
    case Triangle:
        fmt.Println("三角形。。", ins.a, ins.b, ins.c)
    case Circle:
        fmt.Println("圆形。。", ins.radius)
    case *Triangle:
        fmt.Println("三角形结构体指针:", ins.a, ins.b, ins.c)
    }
}

func testShape(s Shape) {
    fmt.Printf("周长:%.2f,面积:%.2f\n", s.peri(), s.area())
}

func main() {
    /*
        接口断言:
            方式一:
                1.instance := 接口对象.(实际类型)     // 不安全,会panic()
                2.instance, ok := 接口对象.(实际类型) // 安全

            方式二:switch
                switch instance := 接口对象.(type){
                case 实际类型1:
                        ....
                case 实际类型2:
                        ....
                ....
                }
    */

    var t1 Triangle = Triangle{3, 4, 5}
    fmt.Println(t1.peri())        // 12
    fmt.Println(t1.area())        // 6
    fmt.Println(t1.a, t1.b, t1.c) // 3 4 5

    var c1 Circle = Circle{4}
    fmt.Println(c1.peri()) // 25.132741228718345
    fmt.Println(c1.area()) // 50.26548245743669
    fmt.Println(c1.radius) // 4

    var s1 Shape
    s1 = t1
    fmt.Println(s1.peri())
    fmt.Println(s1.area())

    var s2 Shape
    s2 = c1
    fmt.Println(s2.peri())
    fmt.Println(s2.area())

    testShape(t1) // 周长:12.00,面积:6.00
    testShape(c1) // 周长:25.13,面积:50.27
    testShape(s1) // 周长:12.00,面积:6.00

    getType(t1) // 是三角形,三边是: 3 4 5
    getType(c1) // 是圆形,半径是: 4
    getType(s1) // 是三角形,三边是: 3 4 5
    // getType(100)

    var t2 *Triangle = &Triangle{3, 4, 2}
    fmt.Printf("t2:%T,%p,%p\n", t2, &t2, t2) // t2:*main.Triangle,0xc000006030,0xc0000121f8
    getType(t2)                              // 自身地址不一样,里面存的地址一样,引用传递
    // ins:*main.Triangle,0xc000006038,0xc0000121f8
    // s:*main.Triangle,0xc000046260,0xc0000121f8
    getType2(t2) // 三角形结构体指针: 3 4 2
    getType2(t1) // 三角形。。 3 4 5

}