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"})
    }
    
  • 相关阅读:
    Vue(小案例_vue+axios仿手机app)_go实现退回上一个路由
    nyoj 635 Oh, my goddess
    nyoj 587 blockhouses
    nyoj 483 Nightmare
    nyoj 592 spiral grid
    nyoj 927 The partial sum problem
    nyoj 523 亡命逃窜
    nyoj 929 密码宝盒
    nyoj 999 师傅又被妖怪抓走了
    nyoj 293 Sticks
  • 原文地址:https://www.cnblogs.com/morya/p/9251889.html
Copyright © 2011-2022 走看看