初学 Golang,对于接口部分有一些不太理解的地方,希望 V 友能帮忙解答一下。

package main

import "fmt"

type Stringer interface {
	String() string
}

type Printer interface {
	Stringer // 接口嵌入。
	Print()
}

type User struct {
	id   int
	name string
}

func (self *User) String() string {
	return fmt.Sprintf("user %d, %s", self.id, self.name)
}

func (self *User) Print() {
	fmt.Println(self.String())
}

func main() {
	var t Printer = &User{1, "Tom"} // *User 方法集包含 String、Print。
	// 如果去掉接口定义的代码,将上一行代码替换为下行,也可以运行,请问接口的作用体现在哪里?
	// var t := User{1, "Tom"}
	t.Print()
}

书上写了接口声明一个方法的签名。声明一个空方法集的接口类型,并将其作为函数参数,函数不会检查传入的是什么类型,只要这个参数满足接口定义即可,即可以通过编译器检查(个人理解)。另外,接口可以进行接口检查,接口嵌入等。我学到了这些理论知识,但对接口缺乏感性的认识。

相对于不定义接口,「直接定义结构体和结构体上的方法」的方式,额外定义了接口会带来什么好处么?

可以举几个实际的例子么?