从接口值中获取底层指针类型

huangapple go评论74阅读模式
英文:

Underlying pointer type from interface value

问题

如何从接口中获取底层指针类型?

package main

import (
	"fmt"
)

type Car interface {
	Drive() string
}

type MyCar struct {
	name string
}

func (MyCar) Drive() string {
	return "rum rum"
}

func main() {
	var car Car
	mycar := &MyCar{name: "mycar"}
	car = mycar
	mycarptr, err := car.(*MyCar)
	mycarvalue, err2 := car.(MyCar)
	fmt.Printf("as ptr failed: %t, as value failed: %t\n", err, err2)
	fmt.Printf("as ptr: %+v, as value: %+v", mycarptr, mycarvalue)
}

你可以使用类型断言来获取接口的底层指针类型。在上面的代码中,car.(*MyCar) 将返回一个指向 MyCar 类型的指针,而 car.(MyCar) 将返回一个 MyCar 类型的值。如果类型断言失败,将返回一个错误。

英文:

How do I get the underlying pointer type from an interface?

package main

import (
	"fmt"
)

type Car interface 	{
	Drive() string
}
type MyCar struct 	{
	name string
}
func (MyCar) Drive (  ) string	{
	return "rum rum"
}


func main() {
	var car Car
	mycar := &MyCar{name:"mycar"}
	car = mycar
	mycarptr, err :=  car.(*MyCar)
	mycarvalue, err2 :=  car.(MyCar)
	fmt.Printf( "as ptr failed: %t, as value failed: %t\n", err, err2 )
	fmt.Printf( "as ptr: %+v, as value: %+v", mycarptr, mycarvalue)
}

答案1

得分: 0

你对 *MyCar 的第一个断言是正确的。

这是一个示例 playground 来说明。

对于 MyCar 的第二个断言将会失败,因为它不是一个指针。

英文:

Your first assertion to *MyCar works fine

Here is a playground example to illustrate

Your second assertion to MyCar will fail since it's not a pointer.

答案2

得分: 0

要能够修改汽车,你需要使用指向它的指针(就像你已经做的那样),但为了让其他人(包括你自己)更清楚,你应该在指针上定义接口方法:

type Drivable interface {
    Drive() string
}

type Car struct {
    name string
}

func (*Car) Drive() string {
    return "rum rum"
}

type SpaceShip struct {
    name string
}

func (*SpaceShip) Drive() string {
    return "当你驾驶/飞行它们时,太空船发出的声音"
}

func Drive(d Drivable) {
    switch d := d.(type) { // d 现在是实际类型
    case *Car:
        fmt.Println("得到了一辆名为", d.name, "的汽车")
    case *SpaceShip:
        fmt.Println("得到了一艘名为", d.name, "的太空船")
    }
}

我建议你阅读《Effective Go》,特别注意《接口和方法》部分。

英文:

To be able to modify the car you need to use a pointer to it (like you already did), however to make it more clear to others (and yourself) you should define the interface method on the pointer:

type Drivable interface {
	Drive() string
}

type Car struct {
	name string
}

func (*Car) Drive() string {
	return "rum rum"
}

type SpaceShip struct {
	name string
}

func (*SpaceShip) Drive() string {
	return "sound spaceships makes when you drive / fly them"
}

func Drive(d Drivable) {
	switch d := d.(type) { // d now is the actual type
	case *Car:
		fmt.Println("Got a car named", d.name)
	case *SpaceShip:
		fmt.Println("Got a spaceship named", d.name)
	}
}

<kbd>playground</kbd>

I recommend going through Effective Go, and pay extra attention to the Interfaces And Methods section.

huangapple
  • 本文由 发表于 2014年9月28日 06:46:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/26079892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定