Golang中请解释为什么会出现这种情况
Golang中请解释为什么会出现这种情况 请解释这个现象:在第一个例子中,dogs方法需要指针,当我在animal切片中声明为&Dog时工作正常,但当我声明为Dog{}时编译器报错:
不能将Dog字面量(类型Dog)作为Animal类型用于数组或切片字面量: Dog未实现Animal(Speak方法具有指针接收器)
但在第二个例子中,当我声明dog的方法不带指针时,使用指针和非指针(&Dog, Dog{})都能正常工作
第一个例子:
package main
import (
"fmt"
)
type Animal interface {
Speak() string
}
type Dog struct {
}
func (d *Dog) Speak() string {
return "BARK!"
}
func main() {
animals := []Animal{&Dog{}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}
第二个例子:
package main
import (
"fmt"
)
type Animal interface {
Speak() string
}
type Dog struct {
}
func (d Dog) Speak() string {
return "BARK!"
}
func main() {
animals := []Animal{Dog{}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}
更多关于Golang中请解释为什么会出现这种情况的实战教程也可以访问 https://www.itying.com/category-94-b0.html
&Dog{} 就是您要找的。 &Dog{} 会在 animal 切片中添加一个新的动物。
func main() {
fmt.Println("hello world")
}
更多关于Golang中请解释为什么会出现这种情况的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
实际上我需要解释,为什么在第一个例子中我只能传递指针(&Dog{}) 而在第二个例子中指针和值都有效(&Dog{}, Dog{})
func main() {
fmt.Println("hello world")
}
在你第一个示例中,尝试将具体类型传递给接口类型时,Dog 本身并未实现 Animal 接口,只有指向 Dog 的指针才实现了该接口。在第二个示例中,(Dog.Speak()) 满足了接口的方法要求。
并非总是能够获取值的地址。由于并非总是能够获取值的地址,因此值的方法集仅包含通过值接收器实现的方法。
01 // 示例程序展示为何有时无法获取值的地址
02 package main
03
04 import "fmt"
05
06 // duration 是基于 int 的自定义类型
07 type duration int
08
09 // format 优雅地格式化 duration 值
10 func (d *duration) pretty() string {
11 return fmt.Sprintf("Duration: %d", *d)
12 }
13
14 // main 是应用程序的入口点
15 func main() {
16 duration(42).pretty()
17
18 // ./listing46.go:17: 无法在 duration(42) 上调用指针方法
19 // ./listing46.go:17: 无法获取 duration(42) 的地址
20 }
清单5.46中的代码尝试获取 duration 类型值的地址但失败了。这表明并非总是能够获取值的地址。让我们再次查看方法集的规则。
在Go语言中,接口实现与方法的接收器类型密切相关。第一个例子中,Speak方法使用指针接收器(d *Dog),这意味着只有*Dog类型(指向Dog的指针)实现了Animal接口。因此,在切片[]Animal中,只能使用&Dog{}(指针),而不能使用Dog{}(值类型),因为值类型Dog没有实现Speak方法。
第二个例子中,Speak方法使用值接收器(d Dog),这允许Dog和*Dog类型都实现Animal接口。Go语言会自动处理值类型和指针类型的转换,因此Dog{}和&Dog{}都可以在切片中使用。
示例代码说明:
第一个例子(指针接收器):
&Dog{}是*Dog类型,实现了Animal接口。Dog{}是Dog类型,未实现Animal接口,导致编译器错误。
第二个例子(值接收器):
Dog{}是Dog类型,实现了Animal接口。&Dog{}是*Dog类型,也实现了Animal接口(通过自动解引用)。
这种行为是Go语言类型系统的一部分,确保接口实现的一致性。如果方法需要修改接收器的状态,应使用指针接收器;否则,值接收器更高效。

