使用 String() 方法來客製化字符串的輸出

https://wiki.jikexueyuan.com/project/the-way-to-go/10.7.html

当定义了一个有很多方法的类型时,十之八九你会使用 String() 方法来定制类型的字符串形式的输出,换句话说:一种可阅读性和打印性的输出。如果类型定义了 String() 方法,它会被用在 fmt.Printf() 中生成默认的输出:等同于使用格式化描述符 %v 产生的输出。还有 fmt.Print() 和 fmt.Println() 也会自动使用 String() 方法。

範例:https://play.golang.org/p/MM33SftL5GO

当你广泛使用一个自定义类型时,最好为它定义 String()方法。从上面的例子也可以看到,格式化描述符 %T 会给出类型的完全规格,%#v 会给出实例的完整输出,包括它的字段(在程序自动生成 Go 代码时也很有用)。



备注

不要在 String() 方法里面调用涉及 String() 方法的方法,它会导致意料之外的错误。

Golang: 合併 slice 的 append 方法

範例:https://play.golang.org/p/tTMQ2l8W--B

x := []int{1, 2, 3}
y := []int{4, 5, 6}

fmt.Println(append(x, 4, 5, 6))
fmt.Println(append(x, y...))

輸出結果:

[1 2 3 4 5 6]
[1 2 3 4 5 6]

append 的用法有兩種:
slice = append(slice, 元素1, 元素2)
slice = append(slice, anotherSlice...)

第一種用法的第一個參數為 slice,後面可以添加多個元素。

第二種用法是將兩個 slice 拼接在一起,且需要在第二個 slice 的名稱後面加三個點,
這時候 append 只支持兩個 slice 拼接,不支持任意數量。

觀古鑑今:同一件歷史,卻有完全相反的分析結論

30多年前,日本是如何輸掉晶片這場戰爭的?


認為是美國聯手韓國,鬥垮日本的:
https://www.techbang.com/posts/70406-how-did-japan-lose-its-chip-war-more-than-30-years-ago

認為日本不是因為美國才「輸」掉芯片戰爭,日本是輸給自己:
https://chinaqna.com/a/83585



同一件歷史,卻有完全相反的分析結論 ...
我們在這些分析與思考的過程中,學到了甚麼?

Cache 和 Buffer 都是緩存,區別為何?

1、Buffer(緩衝區)是系統兩端處理速度平衡(從長時間尺度上看)時使用的。它的引入是為了減小短期內突發I/O的影響,起到流量整形的作用。比如生產者——消費者問題,他們產生和消耗資源的速度大體接近,加一個buffer可以抵消掉資源剛產生/消耗時的突然變化。

2、Cache(緩存)則是系統兩端處理速度不匹配時的一種折衷策略。因為CPU和memory之間的速度差異越來越大,所以人們充分利用數據的局部性(locality)特徵,通過使用存儲系統分級(memory hierarchy)的策略來減小這種差異帶來的影響。

3、假定以後存儲器訪問變得跟CPU做計算一樣快,cache就可以消失,但是buffer依然存在。比如從網絡上下載東西,瞬時速率可能會有較大變化,但從長期來看卻是穩定的,這樣就能通過引入一個buffer使得OS接收數據的速率更穩定,進一步減少對磁盤的傷害。

4、TLB(Translation Lookaside Buffer,後備緩衝器)名字起錯了,其實它是一個cache。


Buffer 的主要目的是進行流量整形,把突發的大數量較小規模的 I/O 整理成平穩的小數量較大規模的 I/O,以減少響應次數(比如從網上下載電影,你不能下一點點數據就寫一下硬盤,而是積攢一定數量的數據後才一整塊一起寫,不然硬碟都要被玩壞了)

Golang: Println、Printf、Sprintf (格式化輸出)

https://studygolang.com/articles/16080
https://blog.csdn.net/zgh0711/article/details/78843361
https://www.jianshu.com/p/9637c18d5f01
https://blog.csdn.net/chenbaoke/article/details/39932845

Println:
1. 用默认的类型格式显示方式将传入的参数写入到标准输出里面(即在终端中有显示),
2. 多个传入参数之间使用空格分隔,
3. 在显示的最后追加换行符,
4. 返回值为 写入标准输出的字节数和写入过程中遇到的问题。
Printf:
1. 用传入的格式化规则符将传入的变量写入到标准输出里面(即在终端中有显示),
2. 返回值为 写入标准输出的字节数和写入过程中遇到的问题。
Sprintf:
1. 用传入的格式化规则符将传入的变量格式化,(终端中不会有显示)
2. 返回为 格式化后的字符串。



Println:可以打印出字符串,和变量
Printf:只可以打印出格式化的字符串,可以输出字符串类型的变量,不可以输出整形变量和整形

也就是说,当需要格式化输出信息时一般选择 Printf,其他时候用 Println




fmt.Sprintf(格式化样式, 参数列表…)
格式化样式:字符串形式,格式化动词以%开头。
参数列表:多个参数以逗号分隔,个数必须与格式化样式中的个数一一对应,否则运行时会报错。

var progress = 2
var target = 8

// 两参数格式化
title := fmt.Sprintf("已采集%d个药草, 还需要%d个完成任务", progress, target)

fmt.Println(title)

pi := 3.14159
// 按数值本身的格式输出
variant := fmt.Sprintf("%v %v %v", "月球基地", pi, true)

fmt.Println(variant)

// 匿名结构体声明, 并赋予初值
profile := &struct {
    Name string
    HP   int
}{
    Name: "rat",
    HP:   150,
}

fmt.Printf("使用'%%+v' %+v\n", profile)

fmt.Printf("使用'%%#v' %#v\n", profile)

fmt.Printf("使用'%%T' %T\n", profile)
代码输出如下:
已采集2个药草, 还需要8个完成任务
"月球基地" 3.14159 true
使用'%+v' &{Name:rat HP:150}
使用'%#v' &struct { Name string; HP int }{Name:"rat", HP:150}
使用'%T' *struct { Name string; HP int }C语言中, 使用%d代表整型参数

下表中标出了常用的一些格式化样式中的动词及功能。

表:字符串格式化时常用动词及功能
动  词功  能
%v按值的本来值输出
%+v在 %v 基础上,对结构体字段名和值进行展开
%#v输出 Go 语言语法格式的值
%T输出 Go 语言语法格式的类型和值
%%输出 % 本体
%b整型以二进制方式显示
%o整型以八进制方式显示
%d整型以十进制方式显示
%x整型以十六进制方式显示
%X整型以十六进制、字母大写方式显示
%UUnicode 字符
%f浮点数
%p指针,十六进制方式显示


程式語言編年史

程式語言編年史原文 下面這張圖片描繪了整個程式語言的歷史。包括各種程式語言的發明人、程式語言的特點和適用領域、被什麼網站或公司使用等 (檢視 完整高清圖 )。 之所以會有那麼多不同的程式語言是因為設計程式語言的初衷不同、對語言學習曲線的追求不同、不同程式之間的執行成本差異...