1. 方法

方法是附加到特定类型的函数。它们可以接收值接收者或指针接收者。

1.1 值接收者方法

值接收者方法使用类型的值作为接收者。这种方法接收一个类型的副本,因此不能修改原始值。

package main

import "fmt"

type Rectangle struct {
    Width, Height int
}

// 值接收者方法
func (r Rectangle) Area() int {
    return r.Width * r.Height
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    fmt.Println("Area:", rect.Area()) // 输出: Area: 50
}

1.2 指针接收者方法

指针接收者方法使用类型的指针作为接收者。这种方法可以修改原始值。

package main

import "fmt"

type Rectangle struct {
    Width, Height int
}

// 指针接收者方法
func (r *Rectangle) Scale(factor int) {
    r.Width *= factor
    r.Height *= factor
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    rect.Scale(2)
    fmt.Println("Scaled Area:", rect.Area()) // 输出: Scaled Area: 200
}

2. 接口

接口定义了一组方法,具体类型可以实现这些方法。接口类型变量可以存储任何实现了该接口的值。

2.1 定义接口

定义一个接口,使用关键字 interface

package main

import "fmt"

// 定义一个接口
type Shape interface {
    Area() int
}

type Rectangle struct {
    Width, Height int
}

// 实现接口方法
func (r Rectangle) Area() int {
    return r.Width * r.Height
}

func main() {
    var s Shape
    s = Rectangle{Width: 10, Height: 5}
    fmt.Println("Area:", s.Area()) // 输出: Area: 50
}

2.2 多个类型实现同一接口

多个类型可以实现同一个接口。

package main

import "fmt"

type Shape interface {
    Area() int
}

type Rectangle struct {
    Width, Height int
}

type Circle struct {
    Radius int
}

// 实现接口方法
func (r Rectangle) Area() int {
    return r.Width * r.Height
}

func (c Circle) Area() int {
    return 3 * c.Radius * c.Radius // 假设π≈3
}

func main() {
    var s Shape
    s = Rectangle{Width: 10, Height: 5}
    fmt.Println("Rectangle Area:", s.Area()) // 输出: Rectangle Area: 50

    s = Circle{Radius: 3}
    fmt.Println("Circle Area:", s.Area()) // 输出: Circle Area: 27
}

2.3 空接口

空接口 interface{} 可以存储任何类型的值。

package main

import "fmt"

func describe(i interface{}) {
    fmt.Printf("Type: %T, Value: %v\n", i, i)
}

func main() {
    describe(42)
    describe("hello")
    describe(true)
}

2.4 类型断言

类型断言用于将接口类型变量转换为具体类型。

package main

import "fmt"

func main() {
    var i interface{} = "hello"

    // 类型断言
    s, ok := i.(string)
    if ok {
        fmt.Println(s) // 输出: hello
    } else {
        fmt.Println("Conversion failed")
    }
}

2.5 类型选择

类型选择用于处理接口变量的不同具体类型。

package main

import "fmt"

func describe(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Println("Integer:", v)
    case string:
        fmt.Println("String:", v)
    default:
        fmt.Println("Unknown type")
    }
}

func main() {
    describe(42)
    describe("hello")
    describe(true)
}

示例代码

以下是一个包含方法和接口综合使用的完整示例代码:

package main

import "fmt"

// 定义一个接口
type Shape interface {
    Area() int
}

// 定义一个矩形结构体
type Rectangle struct {
    Width, Height int
}

// 实现接口方法
func (r Rectangle) Area() int {
    return r.Width * r.Height
}

// 定义一个圆形结构体
type Circle struct {
    Radius int
}

// 实现接口方法
func (c Circle) Area() int {
    return 3 * c.Radius * c.Radius // 假设π≈3
}

// 定义一个打印面积的函数
func printArea(s Shape) {
    fmt.Println("Area:", s.Area())
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    circle := Circle{Radius: 3}

    printArea(rect)   // 输出: Area: 50
    printArea(circle) // 输出: Area: 27

    // 使用空接口
    var i interface{}
    i = 42
    describe(i) // 输出: Type: int, Value: 42

    i = "hello"
    describe(i) // 输出: Type: string, Value: hello
}

func describe(i interface{}) {
    fmt.Printf("Type: %T, Value: %v\n", i, i)
}

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://example.com/subject/article/86/

许可协议:署名-非商业性使用 4.0 国际许可协议