Go 语义-将外部接口类型值传递给内部接口变量

Go 语义-将外部接口类型值传递给内部接口变量,go,Go,下面是3层API的原型代码(有一些设计限制): 我的理解是, 如果您通过u,则该界面包含u的类型,以及指向u副本的指针。如果您通过&u,则界面包含&u的类型和u的地址 下面是我对变量p,s和ps的理解,来自上述代码: 但是我想确认一下, 1) 在pull(ps,data)上,p的第一个元素是否包含type*System或Xeniatype作为第一个元素 2) 在store(ps,data[:i])上,s的第一个元素是否包含类型*系统或支柱类型?类型是*系统 您可以通过添加简单的print语句来

下面是3层API的原型代码(有一些设计限制):


我的理解是,

如果您通过
u
,则该界面包含
u
的类型,以及指向
u
副本的指针。如果您通过
&u
,则界面包含
&u
的类型和
u
的地址

下面是我对变量
p
s
ps
的理解,来自上述代码:

但是我想确认一下,

1) 在
pull(ps,data)
上,
p
的第一个元素是否包含type
*System
Xenia
type作为第一个元素


2) 在
store(ps,data[:i])
上,
s
的第一个元素是否包含类型
*系统
支柱
类型?

类型是
*系统


您可以通过添加简单的print语句来确认这一点,例如,
fmt.Printf(“%T\n”,p)

请给出一个简单的示例。
ps
p
s
中的具体类型是
*System
。值的具体类型不会通过赋值给接口变量而改变。@CeriseLimón升级的
Pull()
方法实现是这样的吗<代码>函数(s系统)拉取(d*数据)错误{返回s.Xenia.Pull(d)}
// Sample program demonstrating interface composition.
package main

import (
    "errors"
    "fmt"
    "io"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().UnixNano())
}

// =============================================================================

// Data is the structure of the data we are copying.
type Data struct {
    Line string
}

// =============================================================================

// Puller declares behavior for pulling data.
type Puller interface {
    Pull(d *Data) error
}

// Storer declares behavior for storing data.
type Storer interface {
    Store(d *Data) error
}

// PullStorer declares behavior for both pulling and storing.
type PullStorer interface {
    Puller
    Storer
}

// =============================================================================

// Xenia is a system we need to pull data from.
type Xenia struct {
    Host    string
    Timeout time.Duration
}

// Pull knows how to pull data out of Xenia.
func (*Xenia) Pull(d *Data) error {
    switch rand.Intn(10) {
    case 1, 9:
        return io.EOF

    case 5:
        return errors.New("Error reading data from Xenia")

    default:
        d.Line = "Data"
        fmt.Println("In:", d.Line)
        return nil
    }
}

// Pillar is a system we need to store data into.
type Pillar struct {
    Host    string
    Timeout time.Duration
}

// Store knows how to store data into Pillar.
func (*Pillar) Store(d *Data) error {
    fmt.Println("Out:", d.Line)
    return nil
}

// =============================================================================

// System wraps Xenia and Pillar together into a single system.
type System struct {
    Xenia
    Pillar
}

// =============================================================================

// pull knows how to pull bulks of data from any Puller.
func pull(p Puller, data []Data) (int, error) {
    for i := range data {
        if err := p.Pull(&data[i]); err != nil {
            return i, err
        }
    }

    return len(data), nil
}

// store knows how to store bulks of data from any Storer.
func store(s Storer, data []Data) (int, error) {
    for i := range data {
        if err := s.Store(&data[i]); err != nil {
            return i, err
        }
    }

    return len(data), nil
}

// Copy knows how to pull and store data from any System.
func Copy(ps PullStorer, batch int) error {
    data := make([]Data, batch)

    for {
        i, err := pull(ps, data)
        if i > 0 {
            if _, err := store(ps, data[:i]); err != nil {
                return err
            }
        }

        if err != nil {
            return err
        }
    }
}

// =============================================================================

func main() {
    sys := System{
        Xenia: Xenia{
            Host:    "localhost:8000",
            Timeout: time.Second,
        },
        Pillar: Pillar{
            Host:    "localhost:9000",
            Timeout: time.Second,
        },
    }

    if err := Copy(&sys, 3); err != io.EOF {
        fmt.Println(err)
    }
}