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

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

Underlying pointer type from interface value

问题

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Car interface {
  6. Drive() string
  7. }
  8. type MyCar struct {
  9. name string
  10. }
  11. func (MyCar) Drive() string {
  12. return "rum rum"
  13. }
  14. func main() {
  15. var car Car
  16. mycar := &MyCar{name: "mycar"}
  17. car = mycar
  18. mycarptr, err := car.(*MyCar)
  19. mycarvalue, err2 := car.(MyCar)
  20. fmt.Printf("as ptr failed: %t, as value failed: %t\n", err, err2)
  21. fmt.Printf("as ptr: %+v, as value: %+v", mycarptr, mycarvalue)
  22. }

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

英文:

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Car interface {
  6. Drive() string
  7. }
  8. type MyCar struct {
  9. name string
  10. }
  11. func (MyCar) Drive ( ) string {
  12. return "rum rum"
  13. }
  14. func main() {
  15. var car Car
  16. mycar := &MyCar{name:"mycar"}
  17. car = mycar
  18. mycarptr, err := car.(*MyCar)
  19. mycarvalue, err2 := car.(MyCar)
  20. fmt.Printf( "as ptr failed: %t, as value failed: %t\n", err, err2 )
  21. fmt.Printf( "as ptr: %+v, as value: %+v", mycarptr, mycarvalue)
  22. }

答案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

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

  1. type Drivable interface {
  2. Drive() string
  3. }
  4. type Car struct {
  5. name string
  6. }
  7. func (*Car) Drive() string {
  8. return "rum rum"
  9. }
  10. type SpaceShip struct {
  11. name string
  12. }
  13. func (*SpaceShip) Drive() string {
  14. return "当你驾驶/飞行它们时,太空船发出的声音"
  15. }
  16. func Drive(d Drivable) {
  17. switch d := d.(type) { // d 现在是实际类型
  18. case *Car:
  19. fmt.Println("得到了一辆名为", d.name, "的汽车")
  20. case *SpaceShip:
  21. fmt.Println("得到了一艘名为", d.name, "的太空船")
  22. }
  23. }

我建议你阅读《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:

  1. type Drivable interface {
  2. Drive() string
  3. }
  4. type Car struct {
  5. name string
  6. }
  7. func (*Car) Drive() string {
  8. return "rum rum"
  9. }
  10. type SpaceShip struct {
  11. name string
  12. }
  13. func (*SpaceShip) Drive() string {
  14. return "sound spaceships makes when you drive / fly them"
  15. }
  16. func Drive(d Drivable) {
  17. switch d := d.(type) { // d now is the actual type
  18. case *Car:
  19. fmt.Println("Got a car named", d.name)
  20. case *SpaceShip:
  21. fmt.Println("Got a spaceship named", d.name)
  22. }
  23. }

<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:

确定