【问题标题】:Golang Parameters conversionGolang 参数转换
【发布时间】:2018-03-03 13:36:12
【问题描述】:

有人能解释一下这是怎么发生的吗?

我把interface 作为一个函数的参数。在调用此函数时,我将 struct 传递给它,但它没有给我错误。这是代码

package main

import (
    "fmt"
    "github.com/myusername/gomodel/domain"
    "github.com/myusername/gomodel/model"
)

func main() {
    db := model.InitDB()

    newFunc(db)
}


func newFunc(db domain.IUser) {

    r, err := db.CreateUserTable()
    if err != nil {
        fmt.Println("error", err)
    }
    fmt.Println(r)
}

我已经在代码中的其他地方实现了接口,因为程序只是按照预期实现的接口工作。 IUser 是一个接口,其成员是:

type IUser interface {
    CreateUserTable() (sql.Result, error)
}

InitDB是一个打开数据库并返回数据库结构的函数:

type DB struct {
    *sql.DB
}

//InitDB initializes the database
func InitDB() *DB {
    db, err := sql.Open(dbDriver, dbName)
    if err != nil {
        log.Fatal("failed to initialize database: ",err)
    }
    err2 := db.Ping()
    if err2 != nil {
        log.Fatal(err2)
    }

    return &DB{db}
}

我的问题是:具有参数类型接口的函数如何传递不同类型的参数?这在幕后是如何运作的?

【问题讨论】:

  • 如果*DB 类型实现了CreateUserTable() (sql.Result, error) 方法,那么它隐式实现了接口,并且可以在任何需要该接口的地方使用。
  • ... 见这里:play.golang.org/p/LMI8pcu2gAX,你会注意到编译器在第二种情况下会抱怨,但在第一种情况下不会。在 Go 中,接口是隐式实现的,这意味着你不需要显式声明一个类型实现了一个接口,该类型只需要实现接口的方法集就可以自动使用它。
  • 这就是接口的重点。具体值永远不是接口类型的值,它们是满足接口的其他类型的值,并且允许将它们分配给变量/传递给接口类型的参数。跨度>

标签: go struct interface


【解决方案1】:

根据Golang Spec

接口类型指定了一个称为其接口的方法集。一种 接口类型的变量可以用方法存储任何类型的值 set 是接口的任何超集。据说这种类型 实现接口。

这是因为接口可以实现为每个类型的包装器。接口实际上指向两件事,主要是一个是底层类型,这里是一个结构,另一个是该类型的值,它是一个指向 DB 的指针

您看到newFunc 实际上将interface{} 作为参数,因此您可以将T 类型的任何内容传递给它,也可以是原始类型。

func main() {
    db := model.InitDB()

    newFunc(db)
}

因此,如果您想获取基础值,则需要键入 assert。接口在这里像结构的包装器一样工作,并保存可以使用类型断言获取的类型和值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-10
    • 2014-10-20
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 2017-08-22
    • 1970-01-01
    相关资源
    最近更新 更多