GO 指针*&问题疑问

package main

import (
    "fmt"
)

func main() {
    //var t *stuffClient = NewStuffClient(Connection{})
    //fmt.Println(*t)
    x := NewStuffClient(Connection{})
    fmt.Println(x) // prints &{{} 2 3}
    x = NewStuffClient(
        Connection{},
        WithRetries(1),
    )
    fmt.Println(x) // prints &{{} 2 1}
    x = NewStuffClient(
        Connection{},
        WithRetries(1),
        WithTimeout(1),
    )
    fmt.Println(x) // prints &{{} 1 1}
}

var defaultStuffClientOptions = StuffClientOptions{
    Retries: 3,
    Timeout: 2,
}
type StuffClientOption func(*StuffClientOptions)
type StuffClientOptions struct {
    Retries int //number of times to retry the request before giving up
    Timeout int //connection timeout in seconds
}
func WithRetries(r int) StuffClientOption {
    return func(o *StuffClientOptions) {
        o.Retries = r
    }
}
func WithTimeout(t int) StuffClientOption {
    return func(o *StuffClientOptions) {
        o.Timeout = t
    }
}
type StuffClient interface {
    DoStuff() error
}
type stuffClient struct {
    conn    Connection
    timeout int
    retries int
}

type Connection struct {}

func NewStuffClient(conn Connection, opts ...StuffClientOption) StuffClient {
    options := defaultStuffClientOptions
    for _, o := range opts {
        o(&options)
    }
    return &stuffClient{
        conn:    conn,
        retries: options.Retries,
        timeout: options.Timeout,
    }
}
func (c stuffClient) DoStuff() error {
    return nil
}

打印的结果

//&{{} 2 3}
//&{{} 2 1}
//&{{} 1 1}

尝试*取值操作打印结果报错

fmt.Println(*x)
//prog.go:11:17: invalid indirect of x (type StuffClient)
//Program exited.

如果接口不能进去*取值操作,那func return为啥返回&呢?

已邀请:

simple - 既要有梦想,又要有实力

赞同来自: tangmo

星号主要作用在指针变量上,用来获取指针指向的内存区域的实际值。
在你的例子中虽然你把一个指针变量赋值给了一个接口变量,但接口变量并不属于指针变量。
你若想用*取值,需要先做类型转换:

y := x.(*stuffClient)
fmt.Println(*y)

lichao2018

赞同来自:

接口和实现的关系,* stuffClient是接口StuffClient的一个实现,golang接口不能被解地址或者解引用

要回复问题请先登录注册