在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 通訊
版權(quán)
簡介
Bibliography
接口
通訊
函數(shù)
進(jìn)階
索引
并發(fā)

通訊

在這章中將介紹 Go 中與外部通訊的通訊模塊。將會(huì)了解文件、目錄、網(wǎng)絡(luò)通訊和運(yùn)行其他程序。Go 的 I/O 核心是接口 io.Reader 和 io.Writer。

在 Go 中,從文件讀?。ɑ?qū)懭耄┦欠浅H菀椎摹3绦蛑恍枰褂?os 包就可以從文件 /etc/passwd 中讀取數(shù)據(jù)。

http://wiki.jikexueyuan.com/project/learn-go-language/images/178.png" alt="pic" />

接下來展示了如何做到這點(diǎn):

  1. 打開文件,os.Open 返回一個(gè)實(shí)現(xiàn)了 io.Reader 和 io.Writer 的 *os.File;
  2. 確保關(guān)閉了 f;
  3. 一次讀取 1024 字節(jié);
  4. 到達(dá)文件末尾;
  5. 將內(nèi)容寫入 os.Stdout

如果想要使用緩沖 IO,則有 bufio 包:

http://wiki.jikexueyuan.com/project/learn-go-language/images/179.png" alt="pic" />

0 .打開文件;

  1. 轉(zhuǎn)換 f 為有緩沖的 Reader。NewReader 需要一個(gè) io.Reader,因此或許你認(rèn)為這會(huì)出錯(cuò)。但其實(shí)不會(huì)。任何有 Read() 函數(shù)就實(shí)現(xiàn)了這個(gè)接口。同時(shí),從列表 7.1可以看到,*os.File 已經(jīng)這樣做了;

  2. 從 Reader 讀取,而向 Writer 寫入,然后向屏幕輸出文件。

io.Reader

在前面已經(jīng)提到 io.Reader 接口對(duì)于 Go 語言來說非常重要。許多(如果不是全部的話)函數(shù)需要通過 io.Reader 讀取一些數(shù)據(jù)作為輸入。為了滿足這個(gè)接口,只需要實(shí)現(xiàn)一個(gè)方法:Read(p []byte) (n int, err error)。寫入則是(你可能已經(jīng)猜到了)實(shí)現(xiàn)了 Write 方法的 io.Writer。如果你讓自己的程序或者包中的類型實(shí)現(xiàn)了 io.Reader 或者 io.Writer 接口,那么整個(gè) Go 標(biāo)準(zhǔn)庫都可以使用這個(gè)類型!

一些例子

前面的程序?qū)⒄麄€(gè)文件讀出,但是通常情況下會(huì)希望一行一行的讀取。下面的片段展示了如何實(shí)現(xiàn):

http://wiki.jikexueyuan.com/project/learn-go-language/images/180.png" alt="pic" />

更加通用(但是也更加復(fù)雜)的方法是 ReadLine,參閱包 bufio 的文檔了解更多內(nèi)容。

在 shell 腳本中通常遇到的場景是需要檢查某個(gè)目錄是否存在,如果不存在,就創(chuàng)建一個(gè)。

http://wiki.jikexueyuan.com/project/learn-go-language/images/181.png" alt="pic" />

這兩個(gè)例子的相似之處展示了 Go 擁有的“腳本” 化特性,例如,用 Go 編寫程序感覺上類似使用動(dòng)態(tài)語言(Python、Ruby、Perl 或者 PHP)。

命令行參數(shù)

來自命令行的參數(shù)在程序中通過字符串 slice os.Args 獲取,導(dǎo)入包 os 即可。flag 包有著精巧的接口,同樣提供了解析標(biāo)識(shí)的方法。這個(gè)例子是一個(gè) DNS 查詢工具:

http://wiki.jikexueyuan.com/project/learn-go-language/images/182.png" alt="pic" />

0 .定義 bool 標(biāo)識(shí),-dnssec。變量必須是指針,否則 package 無法設(shè)置其值;

  1. 類似的,port 選項(xiàng);
  2. 簡單的重定義Usage 函數(shù),有點(diǎn)羅嗦;
  3. 指定的每個(gè)標(biāo)識(shí),PrintDefaults 將輸出幫助信息;
  4. 解析標(biāo)識(shí),并填充變量。

當(dāng)參數(shù)被解析之后,就可以使用它們:

http://wiki.jikexueyuan.com/project/learn-go-language/images/183.png" alt="pic" />

執(zhí)行命令

os/exec 包有函數(shù)可以執(zhí)行外部命令,這也是在 Go 中主要的執(zhí)行命令的方法。通過定義一個(gè)有著數(shù)個(gè)方法的*exec.Cmd 結(jié)構(gòu)來使用。

執(zhí)行 ls -l:

import "os/exec"
cmd := exec.Command("/bin/ls", "-l")
err := cmd.Run()

上面的例子運(yùn)行了 “l(fā)s -l”,但是沒有對(duì)其返回的數(shù)據(jù)進(jìn)行任何處理,通過如下方法從命令行的標(biāo)準(zhǔn)輸出中獲得信息:

http://wiki.jikexueyuan.com/project/learn-go-language/images/184.png" alt="pic" />

網(wǎng)絡(luò)

所有網(wǎng)絡(luò)相關(guān)的類型和函數(shù)可以在 net 包中找到。這其中最重要的函數(shù)是 Dial。當(dāng) Dial 到遠(yuǎn)程系統(tǒng),這個(gè)函數(shù)返回 Conn 接口類型,可以用于發(fā)送或接收信息。函數(shù) Dial 簡潔的抽象了網(wǎng)絡(luò)層和傳輸層。因此 IPv4 或者 IPv6,TCP 或者 UDP 可以共用一個(gè)接口。

通過 TCP 連接到遠(yuǎn)程系統(tǒng)(端口 80),然后是 UDP,最后是 TCP 通過 IPv6,大致是這樣:

http://wiki.jikexueyuan.com/project/learn-go-language/images/185.png" alt="pic" />

如果沒有錯(cuò)誤(由e 返回),就可以使用conn 從套接字中讀寫。在包net 中的原始定義是:

// Read reads data from the connection.
Read(b []byte)(n int, err error)

這使得 conn 成為了 io.Reader。

// Write writes data to the connection.
Write(b []byte)(n int, err error)

這同樣使得 conn 成為了 io.Writer,事實(shí)上 conn 是 io.ReadWriter。

但是這些都是隱含的低層 c,通??偸菓?yīng)該使用更高層次的包。例如 http 包。一個(gè)簡單的 http Get 作為例子:

http://wiki.jikexueyuan.com/project/learn-go-language/images/186.png" alt="pic" />

0 .需要的導(dǎo)入;

  1. 使用 http 的 Get 獲取 html;
  2. 錯(cuò)誤處理;
  3. 將整個(gè)內(nèi)容讀入 b;
  4. 如果一切 OK 的話,打印內(nèi)容。

練習(xí)

Q28. (2) 進(jìn)程

  1. 編寫一個(gè)程序,列出所有正在運(yùn)行的進(jìn)程,并打印每個(gè)進(jìn)程執(zhí)行的子進(jìn)程個(gè)數(shù)。輸出應(yīng)當(dāng)類似:
Pid 0 has 2 children: [1 2]
Pid 490 has 2 children: [1199 26524]
Pid 1824 has 1 child: [7293]
  • 為了獲取進(jìn)程列表,需要得到 ps -e -opid,ppid,comm 的輸出。輸出類似:
PID PPID COMMAND
9024 9023 zsh
19560 9024 ps
  • 如果父進(jìn)程有一個(gè)子進(jìn)程, 就打印 child, 如果多于一個(gè), 就打印 children;
  • 進(jìn)程列表要按照數(shù)字排序,這樣就以 pid 0 開始,依次展示。這里有一個(gè) Perl 版本的程序來幫助上手(或者造成絕對(duì)的混亂)。

http://wiki.jikexueyuan.com/project/learn-go-language/images/187.png" alt="pic" />

Q29. (0) 單詞和字母統(tǒng)計(jì)

1 .編寫一個(gè)從標(biāo)準(zhǔn)輸入中讀取文本的小程序,并進(jìn)行下面的操作:

  1. 計(jì)算字符數(shù)量(包括空格);
  2. 計(jì)算單詞數(shù)量;
  3. 計(jì)算行數(shù)。

換句話說,實(shí)現(xiàn)一個(gè) wc(1)(參閱本地的手冊(cè)頁面),然而只需要從標(biāo)準(zhǔn)輸入讀取。

Q30. (0) Uniq

  1. 編寫一個(gè) Go 程序模仿 Unix 命令 uniq 的功能。程序應(yīng)當(dāng)像下面這樣運(yùn)行,提供一個(gè)下面這樣的列表:
'a' 'b' 'a' 'a' 'a' 'c' 'd' 'e' 'f' 'g'  

它將打印出沒有后續(xù)重復(fù)的項(xiàng)目:

'a' 'b' 'a' 'c' 'd' 'e' 'f'  

下面列出的 7.8 是 Perl 實(shí)現(xiàn)的算法。

http://wiki.jikexueyuan.com/project/learn-go-language/images/188.png" alt="pic" />

Q31. (2) Quine Quine 是一個(gè)打印自己的程序。

  1. 用 Go 編寫一個(gè) Quine 程序。

Q32. (1) Echo 服務(wù)

  1. 編寫一個(gè)簡單的 echo 服務(wù)。使其監(jiān)聽于本地的 TCP 端口 8053 上。它應(yīng)當(dāng)可以讀取一行(以換行符結(jié)尾),將這行原樣返回然后關(guān)閉連接。
  2. 讓這個(gè)服務(wù)可以并發(fā),這樣每個(gè)請(qǐng)求都可以在獨(dú)立的 goroutine 中進(jìn)行處理。

Q33. (2) 數(shù)字游戲

  • 從列表中隨機(jī)選擇六個(gè)數(shù)字:

1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 25; 50; 75; 100

數(shù)字可以多次被選中;

  • 從 1 : : : 1000 中選擇一個(gè)隨機(jī)數(shù)i;

  • 嘗試用先前的六個(gè)數(shù)字(或者其中的幾個(gè))配合運(yùn)算符+,
上一篇:版權(quán)下一篇:簡介