Emacs給Go一個(gè)更好的Playground

題目中雖提到了 Emacs ,但其實(shí)本文主要講述是一個(gè)Emacs的神級(jí)插件---org-mode的故事贴膘。 org-mode 不了解的姆怪,請(qǐng)自行Google!
在未使用 org-mode 前誊役,學(xué)習(xí)和實(shí)驗(yàn)Go的特性(例如 context )的步驟如下:

  • 打開(kāi)終端
  • 跳轉(zhuǎn)到學(xué)習(xí)示例目錄下
  • 創(chuàng)建子目錄贞奋,例如 context , 然后跳入子目錄, 創(chuàng)建 main.go 文件
  • 編寫(xiě)簡(jiǎn)單的示例代碼
  • 編譯和運(yùn)行代碼示例,若出錯(cuò)調(diào)試,返回上個(gè)步驟

上面的過(guò)程有些可精簡(jiǎn),例如在IDE中虚汛,目錄跳轉(zhuǎn)可在對(duì)話(huà)框中完成,代碼的編寫(xiě)皇帮,編譯和運(yùn)行都可在IDE中完成。 在IDE中流程如下:

  • 在學(xué)習(xí)示例目錄下蛋辈,創(chuàng)建一個(gè)新的示例工程
  • 編寫(xiě)簡(jiǎn)單的示例代碼, 編譯和運(yùn)行

在IDE中属拾,整個(gè)流程精簡(jiǎn)了很多将谊。 作為語(yǔ)言使用者,我們可能需要把實(shí)驗(yàn)過(guò)的示例代碼留存渐白,以便能應(yīng)用在日后的開(kāi)發(fā)中尊浓。 上面的兩個(gè)流程,都會(huì)根據(jù)實(shí)驗(yàn)的包或者語(yǔ)言特性纯衍,創(chuàng)建相應(yīng)的子目錄栋齿,經(jīng)過(guò)這樣的處理,代碼示例都聚合到了一起襟诸,方便了翻閱和修改瓦堵。 示例代碼的執(zhí)行結(jié)果,大多是直接輸出到終端的歌亲,你要驗(yàn)證原有示例代碼的執(zhí)行結(jié)果菇用,你必須要重新執(zhí)行代碼,因?yàn)閳?zhí)行結(jié)果并沒(méi)有留存陷揪。 若是這個(gè)示例代碼惋鸥,是很久之前的,可能是一年以前的悍缠, 這個(gè)時(shí)候你看到代碼的時(shí)候卦绣,可能會(huì)時(shí)一臉懵逼。 這個(gè)時(shí)候你會(huì)想飞蚓,為什么當(dāng)時(shí)沒(méi)有多留些信息滤港,讓我知道,為什么做這個(gè)示例玷坠,以及這段代碼完成了什么功能蜗搔。

Org-mode 簡(jiǎn)單配置后, 可完美的解決以上問(wèn)題八堡,代碼留存樟凄,執(zhí)行結(jié)果留存,文學(xué)編程(在編碼過(guò)程中書(shū)寫(xiě)文檔)兄渺。

上圖展示了一個(gè)子問(wèn)題的各個(gè)部分缝龄,問(wèn)題描述,解決方案挂谍,代碼叔壤,以及代碼的執(zhí)行結(jié)果。 子問(wèn)題對(duì)應(yīng) Org-mode 中的子目錄口叙,然后所有問(wèn)題都可聚合在一個(gè) Org-mode 文檔中炼绘。 現(xiàn)在流程可簡(jiǎn)化為:

  • 跳轉(zhuǎn)到 Org-mode 文檔中
  • 創(chuàng)建子目錄,書(shū)寫(xiě)解決方案妄田,編碼實(shí)現(xiàn)

借助 Org-mode 強(qiáng)大的特性俺亮,可很容易的復(fù)用代碼以及查詢(xún)驮捍。

對(duì)于 Org-mode 不熟悉的,可先瀏覽Org-mode的主頁(yè)脚曾。 Org-mode 通過(guò) Babel 執(zhí)行代碼东且,對(duì)此不熟悉的讀者, 可閱讀我之前翻譯的文檔本讥。

ob-go

Babel 可執(zhí)行多種語(yǔ)言的代碼珊泳, 但官方的收錄的語(yǔ)言支持中,沒(méi)有Go拷沸。 但Go是如此的炙手可熱色查,沒(méi)有官方支持,肯定也會(huì)有先行者實(shí)現(xiàn)支持堵漱。 感謝 popeob-C 實(shí)現(xiàn)了ob-go , 實(shí)現(xiàn)了 Babel 對(duì)于Go的支持综慎。

簡(jiǎn)介

ob-go 使 Org-babel 可執(zhí)行Go代碼。 與解釋語(yǔ)言可直接執(zhí)行不同勤庐,Go需要先編譯為可執(zhí)行文件示惊,然后運(yùn)行。 Go代碼通過(guò) go run 命令編譯和運(yùn)行愉镰。 若代碼中沒(méi)有 main 函數(shù)米罚,默認(rèn)情況下,代碼會(huì)被包裹在簡(jiǎn)單的 main 函數(shù)中丈探。 若 :package 選項(xiàng)沒(méi)設(shè)置并且代碼中沒(méi)有聲明 package 录择, 則 main package 被聲明。 示例如下碗降,代碼被執(zhí)行隘竭,執(zhí)行結(jié)果被回寫(xiě)到 buffer 中。

#+BEGIN_SRC go :imports "fmt"
  fmt.Println("Hello, org-mode")
#+END_SRC

#+RESULTS:
: Hello, org-mode

使用快捷鍵 C-c C-v v 可查看被擴(kuò)展后的代碼讼渊。

Go特定的頭參數(shù)(Header Arguments)

除了 Babel 的常規(guī)頭參數(shù)之外动看,下面是一些Go語(yǔ)言特定的頭文件。

  • :args: 傳遞命令行參數(shù)到代碼編譯后的可執(zhí)行文件爪幻,傳遞超過(guò)多參數(shù)菱皆,需要使用 list
  • :flags: 傳遞給 go run 或者 go build 的flags(未使用成功)挨稿。
  • :main: 若沒(méi)設(shè)置 no 仇轻, 代碼將會(huì)被包裹在 main 函數(shù)中。默認(rèn) yes 奶甘。
  • :imports: 為代碼提供 imports 的快捷支持篷店。 當(dāng)處理 main 函數(shù)時(shí),應(yīng)該使用這個(gè)選項(xiàng)臭家。 要 import 多個(gè)包船庇,請(qǐng)使用 list 吭产。
  • :package: 設(shè)置當(dāng)前代碼塊 tangle 時(shí)的包名侣监。 需要: :main no 鸭轮。 若沒(méi)設(shè)置,同時(shí)代碼中沒(méi)有包名聲明橄霉, main 包將被聲明窃爷。
  • :var: ob-go 支持 Babel 的變量,不過(guò)目前還不完備姓蜂。

配置

這里假設(shè)Go的開(kāi)發(fā)環(huán)境已經(jīng)配置完畢按厘,同時(shí)你的機(jī)器上的 EmacsOrg-mode 都是最近的版本,對(duì)于 Babel 都是完整支持的钱慢。 由于 ob-go 沒(méi)有并入 Org-mode 所以需要單獨(dú)配置逮京。 步驟如下:

  • M-x find-library ob-C , 找到的目錄 org-plus-contrib

  • 新建 ob-go.el , 然后把 github中代碼 復(fù)制到新建的文件中

  • 配置 org-babel-load-languages, 如下:

    (org-babel-do-load-languages
     'org-babel-load-languages
     '((python . t)
       (C . t)
       (go . t)
       (emacs-lisp . t)
       (shell . t)))
    

編碼流程

最近在 LeetCode 上做編程訓(xùn)練,這里就以解決上面的問(wèn)題的流程來(lái)做說(shuō)明束莫。

  • 在LeetCode頁(yè)面上懒棉,仔細(xì)閱讀和理解問(wèn)題,這里以 Merge Two Binary Trees 為例

  • 跳轉(zhuǎn)到 leetcode.org 览绿, 創(chuàng)建 merge two binary trees 子目錄

  • 創(chuàng)建名為 merge-two-bt 的Go代碼塊

  • 通過(guò)快捷鍵 C-c ' 打開(kāi)Go語(yǔ)言特定的編輯模式buffer中,然后編碼策严。 在編碼過(guò)程完成后, C-c ' 完成并關(guān)閉編輯buffer饿敲;或者對(duì)自己編輯不滿(mǎn)意妻导, C-c C-k 取消編輯并關(guān)閉編輯buffer。

  • 把定義好的代碼塊整合到一起怀各,然后執(zhí)行(完整代碼)倔韭。

使用示例

導(dǎo)入多個(gè)包

#+BEGIN_SRC go :imports '("fmt" "time")
  fmt.Println("當(dāng)前時(shí)間:", time.Now())
#+END_SRC

#+RESULTS:
: 當(dāng)前時(shí)間: 2017-06-12 18:04:20.562355811 +0800 CST

命令行參數(shù)傳遞

#+BEGIN_SRC go :imports '("fmt" "os") :args '("bable" "golang")
  fmt.Println(os.Args[1], os.Args[2])
#+END_SRC

#+RESULTS:
: bable golang

多入?yún)?/h2>
#+NAME: sum
#+BEGIN_SRC go :imports "fmt" :var a=12 b=13
  fmt.Println(a+b)
#+END_SRC

#+RESULTS:
: 25

#+call: sum(a=22,b=23)

#+RESULTS:
: 45

代碼組織

#+NAME: min
#+BEGIN_SRC  go
  func min(a, b int) int {
    if a > b {
      return b
    } else {
      return a
    }
  }
#+END_SRC

#+NAME: get-min
#+BEGIN_SRC go :var a=0 b=0 :imports "fmt" :noweb strip-export
  <<min>>

  func main() {
    fmt.Println(min(a,b))
  }
#+END_SRC

#+call: get-min(27, 23)

#+RESULTS:
: 23

總結(jié)

Org-mode于我來(lái)說(shuō),就是一個(gè)神器瓢对,打破了我對(duì)一個(gè)編輯器的認(rèn)知寿酌,打破了我對(duì)一個(gè)信息收集器的認(rèn)知。 Org-mode依托于強(qiáng)大的 Emacs, 借助于 Babel, 使文檔和代碼無(wú)縫的結(jié)合在了一起, 一會(huì)編碼沥曹,一會(huì)記錄份名, 一會(huì)調(diào)試,一會(huì)執(zhí)行妓美。 不失為僵腺,學(xué)習(xí)語(yǔ)言,嘗試新工具的不二神器壶栋。 再來(lái)一段Go代碼:

#+BEGIN_SRC go :imports "fmt"
  fmt.Println("Goodbye, Gopher!")
#+END_SRC
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辰如,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贵试,更是在濱河造成了極大的恐慌琉兜,老刑警劉巖凯正,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異豌蟋,居然都是意外死亡廊散,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)梧疲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)允睹,“玉大人,你說(shuō)我怎么就攤上這事幌氮$允埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵该互,是天一觀的道長(zhǎng)米者。 經(jīng)常有香客問(wèn)我,道長(zhǎng)宇智,這世上最難降的妖魔是什么蔓搞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮普筹,結(jié)果婚禮上败明,老公的妹妹穿的比我還像新娘。我一直安慰自己太防,他們只是感情好妻顶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蜒车,像睡著了一般讳嘱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酿愧,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天沥潭,我揣著相機(jī)與錄音,去河邊找鬼嬉挡。 笑死钝鸽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庞钢。 我是一名探鬼主播拔恰,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼基括!你這毒婦竟也來(lái)了颜懊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎河爹,沒(méi)想到半個(gè)月后匠璧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咸这,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年夷恍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炊苫。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裁厅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侨艾,到底是詐尸還是另有隱情,我是刑警寧澤拓挥,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布唠梨,位于F島的核電站,受9級(jí)特大地震影響侥啤,放射性物質(zhì)發(fā)生泄漏当叭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一盖灸、第九天 我趴在偏房一處隱蔽的房頂上張望蚁鳖。 院中可真熱鬧,春花似錦赁炎、人聲如沸醉箕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)讥裤。三九已至,卻和暖如春姻报,著一層夾襖步出監(jiān)牢的瞬間己英,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工吴旋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留损肛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓荣瑟,卻偏偏與公主長(zhǎng)得像治拿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子褂傀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 序言 概述 初始配置 代碼塊代碼塊在 Org-mode 中代碼塊在 Babel 中 源代碼執(zhí)行示例RubyShel...
    brantou閱讀 3,790評(píng)論 0 7
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理忍啤,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,661評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評(píng)論 6 342
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • 這是爸媽在我家住的最后一個(gè)晚上同波,明天他們就要回他們的家了鳄梅,在兩千公里外的長(zhǎng)春,有一個(gè)七十多平米的老樓房未檩,那曾...
    莫聽(tīng)穿林閱讀 1,078評(píng)論 7 5