zoukankan      html  css  js  c++  java
  • go 学习 (四):接口 & 方法

     接口声明

    // 接口声明 语法:接口是一个 函数签名 的集合,函数签名(函数的声明,不包括实现)
    type  interfaceName interface {
            method1(param paramType, param paramType...) (returnName returnType ...)
            method2(param paramType, param paramType...) (returnName returnType ...)
    }
    
    
    // 接口名一般加  er
    type writer interface {
       write(num int) (n int, flag bool)
       cache(p []byte) int
    }
    // 若方法名首字母是大写时,且接口名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
    
    
    // 声明结构体
    type structName struct {
      filed1 filedType
      filed2 filedType
    }
    
    
    // 实现接口中的方法
    func (structVariableName structName) method1 (param paramType, param paramType...) (returnName returnType returName returnType, ...) {
      // do something
    }
    
    func (structVairableName structName) method2 (param paramType, param paramType...) (returnName returnType, returnName returnType,...) {
      // do something
    }
    
    // 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以被忽略
    
    
    
    // 实例
    type Phone interface {
       call(number int) string
    }
    
    // 定义结构体
    type Apple struct {
       name string
    }
    
    type Sony struct {
       name string
    }
    // 实现方法
    func (appleBanner Apple) call(number int) string {
       fmt.Println("param number: ", number)
       fmt.Println("banner name: ", appleBanner.name)
       return "successful"
    }
    
    func (sonyBanner Sony) call(number int) string {
       fmt.Println("param number: ", number)
       fmt.Println("banner name: ", sonyBanner.name)
       return "successful"
    }
    
    func main() {
      var apple = Apple{"apple"}
      apple.call(1031)
    
      sony := Sony{"sony"}
      sony.call(313)
    } 

    实现接口的条件

    • 接口中的方法签名包括:方法名称、方法所需参数、参数类型、方法的返回值、返回值类型;若需要实现接口中的某个方法签名,其上述的五个要点需全部保持一致。
    • 接口被正确的编译使用需要 实现接口中的全部方法

     

    类型与接口、接口与接口

    • 一个类型可以实现多个接口,比如一个 socket 结构体同时实现了 io接口和日志接口。
    • 多个类型可以实现相同的接口 ,一个结构体可以嵌套另一个结构体,若一个接口有多个方法需要实现,可以某个结构体实现其中几个方法,剩下的方法由另一个结构体实现。
    // 包含 开启方法和写日志方法 的服务接口
    type Service interface {
        Start()  // 开启服务
        Log(string)  // 日志输出
    }
    
    // 日志器
    type Logger struct {
    }
    
    // 日志结构体 实现 Log()方法
    func (g *Logger) Log(l string) {
    }
    
    // 游戏服务
    type GameService struct {
        Logger  // 嵌入日志器
    }
    
    // 游戏结构体 Start()方法
    func (g *GameService) Start() {
    }
    
    
    // 使用
    var s Service = new(GameService)
    s.Start()
    s.Log(“hello”)
    • 一个接口同时包含了多个其他接口,产生了一个新的接口
    // 写入接口
    type Writer interface {
       Write(p []byte) (n int, err error)}
    // 关闭接口
    type Closer interface {
         Close() error
    }
    
    
    // 接口嵌套
    type Logger interface {    // 此接口需要两个接口嵌入
            Writer  
            Closer
    }   

    排序接口

    package main
    
    import (
        "fmt"
        "sort"
    )
    
    // 自定义类型 排序
    type Interface interface {
        Len() int                    // 序列内元素数量
        Less(i, j int) bool        // 序列中 索引为i的元素 < 索引为j的元素
        Swap(i , j int)            // 交换两个索引上的元素
    }
    
    // 将字符串定义成 自定义类型 (type 关键字)
    type MyStringList []string        // []string:  字符串切片; 为了能对自定义的字符串切片排序,需要让 MyStringList 实现 Interface 接口
    
    // 方法
    func (stringLists MyStringList) Len() int {
        return len(stringLists)
    }
    
    func (stringLists MyStringList) Less(i, j int) bool {
        return stringLists[i] < stringLists[j]
    }
    
    func (stringLists MyStringList) Swap(i, j int) {
        stringLists[i], stringLists[j] = stringLists[j], stringLists[i]
    }
    
    
    
    // 结构体排序
    type HeroKind int                    // 英雄的种类
    const (                                // 定义 HeroKind 的 value 为常量, 类似枚举
        None HeroKind = iota
        Tank
        Assassin
        Mage
    )
    
    type Hero struct {                  // 定义英雄的结构
        Name string                         // 英雄名字
        Kind HeroKind                  // 英雄种类
    }
    
    type Heros []*Hero             // 英雄切片集合
    // 实现 Interface 接口的三个方法
    func (heros Heros) Len() int {
        return len(heros)
    }
    
    func (heros Heros) Less(i, j int) bool {
        if heros[i].Kind != heros[j].Kind {            // 两个英雄的种类不一致时, 优先的按照 种类数字大小进行对比, 否则 则按照英雄名字对比
            return heros[i].Kind < heros[j].Kind
        }
        return heros[i].Name < heros[j].Name
    }
    
    func (heros Heros) Swap(i, j int) {
        heros[i], heros[j] = heros[j], heros[i]
    }
    
    
    
    // 对切片元素进行排序: sort.Slice()
    
    
    func main() {
        // 1、自定义类型实现排序
        names := MyStringList {
            "3. Triple Kill",
            "5. Penta Kill",
            "2. Double Kill",
            "4. Quadra Kill",
            "1. First Blood",
        }
        fmt.Println(names)
        sort.Sort(names)                // 排序:sort.Interface 用于指定 通用排序算法 和 可能被排序到的序列类型 之间的规定
        fmt.Println(names)
    
    
        // 2、sort 包中的便捷排序
        //names := sort.StringSlice {            // 字符串切片 排序
        //    "3. Triple Kill",
        //    "5. Penta Kill",
        //    "2. Double Kill",
        //    "4. Quadra Kill",
        //    "1. First Blood",
        //}
        //fmt.Println(names)
        //sort.Strings(names)
        //fmt.Println(names)
    
        //nums := sort.IntSlice {                // 整型切片 排序
        //    10,
        //    1,
        //    6,
        //    5,
        //    2,
        //}
        //fmt.Println(nums)
        //sort.Ints(nums)
        //fmt.Println(nums)
    
        //doubles := sort.Float64Slice{            // 双精度小数切片 排序
        //    5.02,
        //    3.31,
        //    10.19,
        //    2.20,
        //    12.12,
        //    6.18,
        //    1.12,
        //}
        //fmt.Println(doubles)
        //sort.Float64s(doubles)
        //fmt.Println(doubles)
    
    
        // 3、结构体排序
        heros := Heros{
            &Hero{"吕布", Tank},
            &Hero{"李白", Assassin},
            &Hero{"妲己", Mage},
            &Hero{"貂蝉", Assassin},
            &Hero{"关羽", Tank},
            &Hero{"诸葛亮", Mage},
        }
        fmt.Println("排序前结构体顺序: ")
        for index, hero := range heros {
            fmt.Print(index, "	")
            fmt.Println(*hero)
        }
    
        //sort.Sort(heros)
    
    
        // 4、对切片元素排序: sort.Slice(slice interface{}, less func(i, j int) bool) {...}
        sort.Slice(heros, func(i, j int) bool {            // 传入 切片 和 在排序时对元素进行判断的回调函数
            if heros[i].Kind != heros[j].Kind {
                return heros[i].Kind < heros[j].Kind
            }
            return heros[i].Name < heros[j].Name
        })
    
    fmt.Println()
    for index, hero := range heros { fmt.Print(index, " ") fmt.Println(*hero) } }
  • 相关阅读:
    使用 Spring 2.5 注释驱动的 IoC 功能
    分页、排序SQL 通用存储过程(转)
    MySQL中group_concat函数
    文本内容分页
    jQuery Pagination Ajax分页插件中文详解(转)
    Cesium组件:Cesiumdraw,基于Vue开发的Cesium基础标绘插件
    tileset格式详解Part2
    css实现div的隐藏
    eltable不透明度&边框
    1rem,1em,1vh,1px含义
  • 原文地址:https://www.cnblogs.com/hsmwlyl/p/11773121.html
Copyright © 2011-2022 走看看