zoukankan      html  css  js  c++  java
  • golang 结构体中的匿名接口

    golang 结构体中的匿名接口

    代码示例

    golang 中,可以给结构体增加匿名field,可参考 unknwon 大神的书。

    匿名字段和内嵌结构体

    但,golang同时也可以给结构体定义一个匿名interface field,用法:

    标准库 sort 中,有下面的写法:

    type Interface interface {
    	Len() int
    	Less(i, j int) bool
    	Swap(i, j int)
    }
    
    type reverse struct {
    	Interface
    }
    
    func (r reverse) Less(i, j int) bool {
    	return r.Interface.Less(j, i)
    }
    
    func Reverse(data Interface) Interface {
    	return &reverse{data}
    }
    

    reverse结构体内嵌了一个Interface的interface,并且,提供了单独的Less函数定义。
    却没有提供 Len, Swap 的定义。

    首先,根据结构体内嵌其它匿名字段的定义,可以推知,理论上,调用reverse.Len, reverse.Swap
    肯定是会直接传递到 reverse.Interface.Lenreverse.Interface.Swap
    即,和直接调用Interface的同名函数没有任何区别。

    但,reverse提供了单独的Less函数,它的实现是颠倒了i,j参数,仍然送入到Interface.Less中去,
    那么,得出的结果与直接使用Interface排序的结果,肯定是相反的。

    为什么如此设计?

    Meaning of a struct with embedded anonymous interface?

    摘录其中比较关键的解释如下:

    1. In this way reverse implements the sort.Interface and we can override a specific method without having to define all the others.
    2. 结构体创建时,可以使用任何实现了Interface的obj来初始化,参考:
    package main
    
    import "fmt"
    
    // some interface
    type Stringer interface {
        String() string
    }
    
    // a struct that implements Stringer interface
    type Struct1 struct {
        field1 string
    }
    
    func (s Struct1) String() string {
        return s.field1
    }
    
    
    // another struct that implements Stringer interface, but has a different set of fields
    type Struct2 struct {
        field1 []string
        dummy bool
    }
    
    func (s Struct2) String() string {
        return fmt.Sprintf("%v, %v", s.field1, s.dummy)
    }
    
    
    // container that can embedd any struct which implements Stringer interface
    type StringerContainer struct {
        Stringer
    }
    
    
    func main() {
        // the following prints: This is Struct1
        fmt.Println(StringerContainer{Struct1{"This is Struct1"}})
        // the following prints: [This is Struct1], true
        fmt.Println(StringerContainer{Struct2{[]string{"This", "is", "Struct1"}, true}})
        // the following does not compile:
        // cannot use "This is a type that does not implement Stringer" (type string)
        // as type Stringer in field value:
        // string does not implement Stringer (missing String method)
        fmt.Println(StringerContainer{"This is a type that does not implement Stringer"})
    }
    
  • 相关阅读:
    RAID技术
    Mysql的用户基本操作
    LNMP之Php的安装配置
    java 实现图片拼接
    java 实现Serv-U FTP 和 SFTP 上传 下载
    Image合并添加文字内容
    AOP切面用于系统日志
    网页评论实现
    java web 实体类生成
    java接口调试思想
  • 原文地址:https://www.cnblogs.com/morya/p/9251889.html
Copyright © 2011-2022 走看看