在Go语言中,可以稍后为接口的底层对象分配新值。

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

Assign new values later to the underlying object of the interface in go

问题

我正在尝试在下面的代码中为接口的底层结构分配新值。但它保留了旧值。以下是示例代码。

package main

import (
	"fmt"
	"math"
)

type Shape interface {
	Area() float64
}

type Circle struct {
	Radius float64
	Name   string
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

type Rectangle struct {
	Length float64
	Width  float64
	Name   string
}

func (r Rectangle) Area() float64 {
	return r.Length * r.Width
}

func assignRadius(s Shape, radius float64, name string) {
	switch s := s.(type) {
	case Circle:
		s.Radius = radius
		s.Name = name
	case Rectangle:
		s.Length = radius
		s.Name = name
	}
}

func main() {
	var s Shape
	c := Circle{Radius: 0, Name: "My Circle"}
	s = c
	fmt.Println(s.Area())
	fmt.Println(c.Radius)
	fmt.Println(c.Name)
	assignRadius(s, 10, "My New Circle")
	fmt.Println(c.Radius)
	fmt.Println(c.Name)
}

assignRadius函数中,Shape的类型事先是未知的。我知道这与指针有关,但无法弄清楚。

英文:

I am trying to assign new values to the underlying structure of an interface in code below. But it keeps the older values. Below is the example code.

package main

import (
	"fmt"
	"math"
)

type Shape interface {
	Area() float64
}

type Circle struct {
	Radius float64
	Name   string
}

func (c Circle) Area() float64 {
	return math.Pi * c.Radius * c.Radius
}

type Rectangle struct {
	Length float64
	Width  float64
	Name   string
}

func (r Rectangle) Area() float64 {
	return r.Length * r.Width
}

func assignRadius(s Shape, radius float64, name string) {
	switch s := s.(type) {
	case Circle:
		s.Radius = radius
		s.Name = name
	case Rectangle:
		s.Length = radius
		s.Name = name
	}
}

func main() {
	var s Shape
	c := Circle{Radius: 0, Name: "My Circle"}
	s = c
	fmt.Println(s.Area())
	fmt.Println(c.Radius)
	fmt.Println(c.Name)
	assignRadius(s, 10, "My New Circle")
	fmt.Println(c.Radius)
	fmt.Println(c.Name)
}

The type of Shape isn't known beforehand in the assignRadius. I know it has something to do with the pointers. But can't figure it out.

答案1

得分: 2

接口变量s包含了形状值的一个副本。要像你尝试的那样修改它,它必须包含指向该形状的指针:

var s Shape
c := Circle{Radius: 0, Name: "My Circle"}
s = &c

在修改它们的函数中,你必须对指针值进行类型断言:

func assignRadius(s Shape, radius float64, name string) {
    switch s := s.(type) {
    case *Circle:
        s.Radius = radius
        s.Name = name
    case *Rectangle:
        s.Length = radius
        s.Name = name
    }
}
英文:

The interface variable s contains a copy of the shape value. To modify it like you attempted to do, it has to contain a pointer to that shape:

var s Shape
c := Circle{Radius: 0, Name: "My Circle"}
s = &c

and in the function modifying them, you have to type-assert the pointer value:

func assignRadius(s Shape, radius float64, name string) {
    switch s := s.(type) {
    case *Circle:
        s.Radius = radius
        s.Name = name
    case *Rectangle:
        s.Length = radius
        s.Name = name
    }




</details>



huangapple
  • 本文由 发表于 2023年6月2日 23:59:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76391738.html
匿名

发表评论

匿名网友

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

确定