Golang中类型系统的困惑与解析

Golang中类型系统的困惑与解析

var now time.Time = time.now()

是有效的,因为 time.now() 返回一个 time.Time 类型的值。

但是显然

var replacer strings.Replacer = strings.NewReplacer("#", "o")

是不正确的!为什么? 我以为变量 replacer 应该是 strings.Replacer 类型?

需要说明的是,我正在尝试理解《Head First Go》这本书(纸质版)第32和33页中解释的内容。

3 回复

确实。谢谢。

我本该先读文档的!

go doc strings NewReplacer func NewReplacer(oldnew …string) *Replacer (它返回一个指针)

func NewReplacer(oldnew …string) *Replacer

更多关于Golang中类型系统的困惑与解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


strings.NewReplacer 返回一个指向 strings.Replacer 结构体的指针,而不是结构体本身,因此你需要将代码修改为:

var replacer *strings.Replacer = strings.NewReplacer("#", "o")

或者

replacer := strings.NewReplacer("#", "o")

在Go语言中,strings.Replacer 是一个接口类型,而 strings.NewReplacer 返回的是一个指向未导出结构体(*strings.replacer)的指针。接口变量可以存储任何实现了该接口的具体类型的值,包括指针类型。因此,正确的声明方式应该使用接口类型来接收返回值,或者让Go自动推断类型。

以下是正确的代码示例:

package main

import (
    "fmt"
    "strings"
)

func main() {
    // 正确:使用接口类型声明,返回的是 *strings.replacer(实现了 strings.Replacer 接口)
    var replacer strings.Replacer = strings.NewReplacer("#", "o")
    fmt.Println(replacer.Replace("G# l#ng")) // 输出: Go lang

    // 更简洁的方式:使用类型推断
    replacer2 := strings.NewReplacer("#", "o")
    fmt.Println(replacer2.Replace("Head First G#")) // 输出: Head First Go
}

关键点:

  1. strings.Replacer 是一个接口,定义在 strings 包中。
  2. strings.NewReplacer 返回的是 *strings.replacer(注意小写,未导出类型),但它实现了 strings.Replacer 接口。
  3. 接口变量可以存储实现该接口的任何具体类型的值,所以 var replacer strings.Replacer = ... 是有效的。

在《Head First Go》中提到的例子可能强调了接口与具体类型的区别。time.Time 是一个具体结构体类型,而 strings.Replacer 是接口,两者在类型系统中有不同行为。

回到顶部