mock.Retriever.String()为什么会被自动运行

来源:6-6 常用系统接口

阿憨阿憨

2018-12-26

老师我想问下为什么mock.Retriever.String()会被自动自行了一下?是因为我注释了写的那个原因吗?

任何实体有String() 方法,当采用任何接受字符的verb(%v %s %q %x %X)动作格式化一个操作数时,或者被不使用格式字符串如Print函数打印操作数时,会调用String方法来生成输出的文本。

package mock

import "fmt"

type Retriever struct {
	Content string
}
//就是看到fmt 中stringEr中的有一個String(),所以我們這裡,重寫一下試試,这个写完之后就相当于是其他语言中的toString
//手册上说, 当采用任何接受字符的verb(%v %s %q %x %X)动作格式化一个操作数时,或者被不使用格式字符串如Print函数打印操作数时,会调用String方法来生成输出的文本。
func (r *Retriever) String() string {
	return fmt.Sprintf("!!!Retriever:{Contests=%s}", r.Content)
}

//这里要修改属性的值,必须用指针方式
func (r *Retriever) Post(url string, form map[string]string) string {
	r.Content = form["Contents"]
	return "ok"
}

//Retriever这里实现的接口和main.go中的无关,只要实现了GET方法方法就可以了
func (r Retriever) Get(url string) string {
	return r.Content
}

func inspect(r Retriever) {
	fmt.Println("Inspecting", r)
	//打印类型
	fmt.Printf("--- %T %v\n", r, r)
	//可以发现改为&mock.Retriever{...,之后下面的case mock.Retriever:不会被命中了输出不了Contents:
	fmt.Printf("--- type switch:\n")
	switch v := r.(type) {
	case mock.Retriever:
		fmt.Println("Contents:", v.Content)
	case *real2.Retriever:
		fmt.Println("UserAgent:", v.UserAgent)
	}
	fmt.Println()
}

func main() {
	//这里是测试 mock.Retriever重写了String方法,而这个方法zai inspect中自动被调用了...
		var r2 Retriever
		retriever2 := mock.Retriever{"这里是百度"}
		r2 = &retriever2
		inspect(r2)
}
写回答

2回答

ccmouse

2018-12-26

是的,同学的理解是正确的

1
2
尼克2018
回复
阿憨阿憨
同学谢谢分享
2021-06-07
共2条回复

EnzoLiu

2020-07-17

楼上说明的都没看懂,一直没能理解这里的string为啥会自动执行

写了个demo 自己懂了,也分享一下,后面学习的小伙伴们可以参考:

package main

import "fmt"

type Test struct {
  content string
}

// 可以把这个string方法屏蔽掉 再对比下结果
func (t Test) String() string {
  return fmt.Sprintf("Content = %s", t.content)
}

func main() {
  r := Test{"这是一个测试"}
  fmt.Println(r)
}


1
0

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程