背景
事情的起因是,想找個(gè)跨 Windows 和 Mac 的構(gòu)建方案。第一考慮自然是 CMake,畢竟基本上是事實(shí)標(biāo)準(zhǔn)了。
但是研究了一下 Modern CMake,也就是以 target 為核心的理念。但發(fā)現(xiàn)看了好幾天文檔,也折騰出了可用的東西,但仍然是沒梳理清楚什么理念、原理。然后 CMake 本身語法就很復(fù)雜,再加上搞 target 一套概念,要給 target 設(shè)置各種屬性之類的,有點(diǎn)強(qiáng)行 OOP 的感覺……但其實(shí)我們只是需要一個(gè) include_dir 和 lib_dir 而已,其他都是浮云~
但如果退回到傳統(tǒng)模式,不用 Modern 概念呢,好像可以將就,但第一不去用一個(gè)工具的最新模式,好像有點(diǎn)不上進(jìn)的感覺(python 2 除外);第二,CMake 的兩大痛點(diǎn)——語法特立獨(dú)行、文檔晦澀難懂——還是讓人有點(diǎn)不爽。
那跳出來看別的選擇呢?目前相對成熟的也只有 Google 的 gn+ninja 方案了。gn 這套東西在 Chromium 里是完全配置好的,用起來還算順手,但要是獨(dú)立拿出來呢,就沒那么便宜了。關(guān)鍵是它的 toolchain 是要自己定義的。
之前還在公司搞客戶端的時(shí)候,大家就從 Chromium 里面把 build、build_overrides 等等東西全部拷出來,好家伙,幾百 MB 甚至上 G。但是公司里嘛,沒人管干不干凈,怎么快怎么來。后來又看到 Google 自家的 Crashpad 里面也用了這套構(gòu)建,但工具鏈被簡化了一下,叫 mini_chromium。這個(gè)比 Chromium 里的小多了,是可以拿過來直接用的,缺少一些配置可以自己加。但是呢,像我們這種潔癖,仍然是受不鳥的。所以呢,我們要干干凈凈的建立一套工具鏈。
構(gòu)建系統(tǒng)安裝
首先,我們明確定位。gn 和 ninja 都是開發(fā)機(jī)上需要預(yù)裝的,不是軟件提供的。Chromium 的搞法是自己提供,gn 的文檔也說讓開發(fā)者提供工具。但這套思路跟傳統(tǒng)的理念是沖突的。同時(shí),自己安裝工具成本是比較低的:
- linux
- ninja 在主流包管理系統(tǒng)里已經(jīng)有了,包名可能是 ninja 或 ninja-build,直接安裝就可以
- gn 在部分包管理系統(tǒng)有,嘗試包名 gn 或 gn-build 等,沒有的話可以下載二進(jìn)制版本,或者從源代碼自行編譯
- mac
- ninja 在 brew 里包名叫 ninja,在 MacPorts 里包名叫 ninja-build
- gn 在 brew 里沒有,可以下載二進(jìn)制版本;在 MacPorts 里叫 gn-devel
- win
自己下載的設(shè)置到 PATH,測試 gn --version
以及 ninja --version
,能運(yùn)行即可
目標(biāo)
希望做到提供一個(gè) git repo,使用者 clone 到自己項(xiàng)目的 build 目錄,然后使用者只要在 .gn 文件里配置
buildconfig = "//build/BUILDCONFIG.gn"
就可以使用我們提供的工具鏈,在 PC 三端進(jìn)行構(gòu)建。
使用者的唯一負(fù)擔(dān)就是編寫自己的 BUILD.gn
工具鏈搭建
首先我們看 gn 的文檔,以及它的例程 simple_build 里的工具鏈配置:
https://gn.googlesource.com/gn/+/HEAD/examples/simple_build/build/toolchain/BUILD.gn
這個(gè)是可以直接用的,只不過只有 linux 端(當(dāng)然 mac 也能用)。我們再結(jié)合 chrome 里的工具鏈配置,進(jìn)行一些完善。
基礎(chǔ)概念
首先我們了解 gn 體系需要的最小配置是什么。
第一,它需要在根目錄寫一個(gè) .gn 文件,在里面定義 buildconfig,指到另一個(gè)文件,一般是
buildconfig = "//build/BUILDCONFIG.gn"
第二、BUILDCONFIG.gn 里面需要設(shè)置默認(rèn)工具鏈,也就是寫一行
set_default_toolchain("//build/toolchain:gcc")
第三、定義工具鏈,如上例的 //build/toolchain:gcc。
需要在 build/toolchain 下建立 BUILD.gn 文件,內(nèi)容是
toolchain("gcc") {
# ...
}
最后在 toolchain 里定義各種 tool。
工具鏈中的工具
這部分文檔在這里:https://gn.googlesource.com/gn/+/main/docs/reference.md#func_tool
簡單復(fù)述一下,可被定義的工具有:
- 編譯工具:
"cc": C 編譯器
"cxx": C++ 編譯器
"cxx_module": 支持 module 的 C++ 編譯器
"objc": Objective C 編譯器
"objcxx": Objective C++ 編譯器
"rc": Windows 資源腳本編譯器
"asm": 匯編器
"swift": Swift 編譯器
- 鏈接工具:
"alink": 靜態(tài)庫鏈接器
"solink": 動(dòng)態(tài)庫鏈接器
"link": 可執(zhí)行文件鏈接器
(其他的就先不看了)
我們來看一下 https://gn.googlesource.com/gn/+/HEAD/examples/simple_build/build/toolchain/BUILD.gn 的一些關(guān)鍵配置:
toolchain("gcc") {
tool("cc") {
command = "gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
# ...
}
tool("cxx") {
command = "g++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
outputs = [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
# ...
}
tool("alink") {
command = "rm -f {{output}} && ar rcs {{output}} {{inputs}}"
outputs = [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
# ...
}
tool("solink") {
command = "g++ -shared {{ldflags}} -o $sofile $os_specific_option @$rspfile"
outputs = [ sofile ]
# ...
}
tool("link") {
command = "g++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
outputs = [ outfile ]
# ...
}
tool("stamp") {
command = "touch {{output}}"
}
tool("copy") {
command = "cp -af {{source}} {{output}}"
}
}
可以看到,cc 和 cxx 執(zhí)行 command 后,生成 .o 文件,然后這些 .o 文件可以作為 alink、solink、link 的 inputs,被它們 command 繼續(xù)使用,最后輸出靜態(tài)庫、動(dòng)態(tài)庫以及可執(zhí)行文件。
其余屬性可以查文檔了解含義。
對比 Chromium 中的配置
Linux
主要配置在這里:https://source.chromium.org/chromium/chromium/src/+/main:build/toolchain/gcc_toolchain.gni
也是 gcc 的,與 simple_build 里的大同小異,沒有特別的。
Mac
主要配置在這里:https://source.chromium.org/chromium/chromium/src/+/main:build/toolchain/apple/toolchain.gni
區(qū)別有:
- 用 clang 系列編譯工具,而不是 gcc
- alink 不是用 ar,而使用 libtool
- solink 的默認(rèn)擴(kuò)展名改成了 dylib
- 用了一個(gè) linker_driver.py 來支持生成 dSYM,在里面調(diào)用了 dsymutil 和 strip
Win
- 編譯用 cl,靜態(tài)庫鏈接用 lib,動(dòng)態(tài)庫和可執(zhí)行文件的鏈接用 link
- lib_switch = "",lib_dir_switch = "/LIBPATH:";前兩者 lib_switch = "-l",lib_dir_switch = "-L"
建立我們的工具鏈
基本上是根據(jù)上面分析的要點(diǎn)配置,最終結(jié)果在此:https://github.com/Streamlet/gn_toolchain
新增的一些差異有:
-
增加全局參數(shù) is_debug,可以在 gn gen out --args="is_debug=true"
傳入。默認(rèn) is_debug 為 false,開啟所有優(yōu)化。
-
mac 下生成 dSYM 不使用 python 腳本,直接是 $ld ... && dsymutil ... && strip
-
mac 下加了一個(gè) template:app_bundle,用來生成 xxx.app,主要配置來自于 create_bundle 文檔里的例子
-
win 下增加了一些配置集
-
動(dòng)態(tài)/靜態(tài)鏈接 CRT://build/config/win:console_subsystem、//build/config/win:static_runtime
-
控制臺(tái)程序、Win32 程序://build/config/win:console_subsystem、//build/config/win:windows_subsystem
這個(gè)其實(shí)一般情況下用不著,只要入口函數(shù)是 main/WinMain,link 默認(rèn)就是控制臺(tái)程序/Win32 程序
-
XP 支持://build/config/win:console_subsystem_xp、//build/config/win:windows_subsystem_xp
具體實(shí)現(xiàn)是鏈接參數(shù)加 /SUBSYSTEM:CONSOLE,5.01 或 /SUBSYSTEM:WINDOWS,5.01。關(guān)鍵是后面的版本號 5.01,為了加版本號則必須指定子系統(tǒng)名稱,所以分了 console_subsystem_xp 和 windows_subsystem_xp。又,xp 這里提供了兩個(gè) subsystem 的配置集,非 xp 也提供兩個(gè)。
但是我們沒有加 _WIN32_WINNT=0x0501、WINVER=0x0501、_USING_V110_SDK71_,也沒有指定必須使用 7.0 版本的 SDK,這些都是非必須的,只要不用到 XP 以后添加的 API 即可。使用者可以在自己的 target 里面定義這些宏。
使用案例
提供一個(gè)使用案例:https://github.com/Streamlet/gn_toolchain_sample
因?yàn)樗?git submodule 形式引用了 https://github.com/Streamlet/gn_toolchain,所以 git clone 以后,需要 git submodule update --init
一下。
然后在根目錄執(zhí)行:(確保 gn 和 ninja 已經(jīng)在 PATH 中)
gn gen out
ninja -C out
即可。
Mac 下會(huì)額外生成一個(gè) objc 項(xiàng)目 objc_console_application 以及一個(gè) app_bundle:ns_application.app。
Win 會(huì)額外生成一個(gè) Win32 項(xiàng)目 win32_application。
Win 下需要先執(zhí)行一下 Visual Studio 帶的命令行環(huán)境,如 VS 2022 Community 的 “x64 Native Tools Command Prompt for VS 2022”,cl 等工具才會(huì)可用。
如果要測試 XP(32位),用“x86 Native Tools Command Prompt for VS 2022”進(jìn)入,CD 到項(xiàng)目目錄,執(zhí)行:
gn gen out --args="target_cpu=\"x86\""
ninja -C out
總結(jié)
我們只用幾十 KB 的大小完成了跨端支持,是很輕量的一個(gè)配置。如果您覺得實(shí)用并認(rèn)可這種方式,歡迎一起來維護(hù)、完善。
posted @
2022-11-06 02:05 溪流 閱讀(13406) |
評論 (0) |
編輯 收藏
這個(gè)“偽需求”是最近才想到的。
關(guān)于文章管理的想法,說來話長。我最初是在 CSDN 寫技術(shù)文章,就用網(wǎng)頁上的編輯器。后來在 CppBlog 寫,用上了 Windows Live Write,一般在 Word 里面寫好,再貼到 WLW 發(fā)布。再后來由于太忙了,一直停到現(xiàn)在。其中除了我懶,有兩個(gè)客觀原因,第一是中間好幾年不搞 C++,那么在 CppBlog 上寫非 C++ 的東西好像有點(diǎn)奇怪;第二是,服務(wù)端的東西真的沒法每天下班自己玩呀,每天下班提心吊膽地看短信報(bào)警,也沒哪個(gè)心情和時(shí)間再去重新開辟一個(gè)和白天工作內(nèi)容迥異的學(xué)習(xí)場景維持下去。(佩服自己找借口的能力~)
前些年,Markdown 興起,GitHub Pages 興起,一眾靜態(tài)博客工具也蓬勃發(fā)展。Markdown 真的太適合用來寫技術(shù)博客了,唯一不足是圖片的處理。盡管如此,我還是花了很大的精力把以前所有的文章都轉(zhuǎn)成了 Markdown。然后曾經(jīng)一度也玩上了 GitHub Pages,用 Huge 生成靜態(tài)博客。然而,博客的這東西我認(rèn)為價(jià)值點(diǎn)和動(dòng)力還是在于交流、碰撞,自己寫自己看,跟存本地沒啥區(qū)別——我的 GitHub Pages 幾乎沒人看……那時(shí)候也沒寫幾篇,大概是 2018 年末到 2019 年初的時(shí)間。
半年前,我想到了近年來第一個(gè)“偽需求”。我嫌 Hugo 這種形態(tài)操作太羅嗦:先寫 Markdown,再放到 source repo 的 post 里,提交一把;再生成靜態(tài)頁面,把 public 提交到 public repo。如果折騰模版啥的,就更復(fù)雜。我就想寫 Markdown,寫完提交一次 .md,能不能就看到呢?甚至干脆不提交,直接同步到服務(wù)端。這樣,就得做一套動(dòng)態(tài)系統(tǒng)(相對于 Hogo 的靜態(tài)頁面)去做這件事,而生成被瀏覽的數(shù)據(jù)的邏輯理論上跟 Hugo 之類的沒本質(zhì)區(qū)別。而一般個(gè)人博客這種文章量,根本不用納入性能上的考量,因此做成動(dòng)態(tài)是完全可操作的。看了下市面上沒有此類的工具,于是就開搞了。我把它叫“NoteIsSite”,GitHub 地址 https://github.com/Streamlet/NoteIsSite,Demo 地址 https://note-is-site.streamlet.org/,然后把我所有的文章也用這個(gè)工具掛在主頁下的一個(gè)子分類,見 https://www.streamlet.org/note/。關(guān)于這個(gè),以后再開一篇文章細(xì)說。
到這里為止,寫的過程代價(jià)很小了。但是剛才說了,博客這東西,對于我的動(dòng)力很大一部分來自于評論、碰撞,還是需要發(fā)到公共平臺(tái)上去的好。最近看到一個(gè)去年離職的前同事的博客 https://gclxry.com/,我驚嘆于人家一直在堅(jiān)持寫。我想我是不是也要撿起來了,還是回歸 CppBlog 吧。于是問題就來了。最近覺得最好用的 Markdown 編輯器是 typora,然后它沒法發(fā)博客;以前的 WLW 雖然還能用,但畢竟不基于 Markdown。然而 typora 不開源,沒法給他加一個(gè)“發(fā)布”功能了事。所以自己做做看?順便入一下 Electron 的坑,以及前端的坑。
花了這么大篇幅把需求來源說完了。至于為什么選 Electron 呢?就是為了快點(diǎn)搞定……
上周學(xué)習(xí)了下 Electron 的 demo 以及打包流程:https://github.com/StreamletStudy/ElectronHelloWorld
然后正式用這個(gè) repo:https://github.com/Streamlet/MarkdownBlog
現(xiàn)在功能就兩個(gè):編輯、發(fā)布。編輯不是所見即所得的,左邊 Markdown,右邊 HTML。發(fā)布要每次填 API 地址、賬號,沒做管理。整個(gè)流程通了,于是停下來寫了這篇文章,用剛寫的工具發(fā)布上來。
發(fā)現(xiàn)了 Electron 的一個(gè)坑,只要在頁面里調(diào)用了 alert,頁面上的焦點(diǎn)就有問題,輸入框再也無法輸入內(nèi)容了。目前用 remote.dialog.* 替代。不知道有沒有正解?
后面的規(guī)劃:
- 搞清楚前端的語言體系,然后選擇用原生 JS 還是它的衍生語言,把工程組織進(jìn)一步完善
- 搞清楚 UI 復(fù)雜度,看要不要選擇一個(gè)虛擬 DOM 方案
- 擼功能,賬號管理等
- 擼功能,做成所見即所得
- 擼功能,支持圖片粘貼、上傳
再后面,先不規(guī)劃,做完了再看。當(dāng)前版本 Release:https://github.com/Streamlet/MarkdownBlog/releases/tag/publish_to_metaweblog_api
posted @
2020-09-20 16:03 溪流 閱讀(2206) |
評論 (0) |
編輯 收藏
(原發(fā)于 GitHub Pages,2019-01-01 23:22:43)
2019 年,我回來了。
不知不覺中,我入 PHP 的坑已經(jīng) 3 年有余,入 Go 的坑也大半年了。作為不評論不舒服斯基星人,自然要對 Go 品頭論足一番的。
總的一句話,Go 的一些特性確實(shí)恰到好處,然而更多的地方卻是平庸、繁瑣、束縛,以至于我想不到它是適合哪些場景的。
靜態(tài)語言里,C、C++ 有著明顯的適用領(lǐng)域:你要想老老實(shí)實(shí)寫程序,不玩任何花招,就用 C 吧,至少你能掌控一切,實(shí)在想玩你還有宏這個(gè)大殺器;你要想玩點(diǎn)花招,那就用 C++,代價(jià)就是需要自身水平更高,能掌控到多大層次就寫多大層次,不懂的不要不懂裝懂去用,總體來說還是安全的。
腳本語言里,如果要隨便寫點(diǎn)什么工具,python 啥的挺方便的;寫點(diǎn)網(wǎng)絡(luò)的,就用世界上最好的語言 PHP 吧。什么?你說 Java?實(shí)在沒辦法,體量太大,公司要你用你就用吧。不過就其本質(zhì)而言,其實(shí) Java 和今天的主角——Go 是同一類的。不是說他們語法像,是指應(yīng)用場景(不過這個(gè)領(lǐng)域拿 PHP 寫顯然會(huì)更爽)。
嗯——為了表達(dá)出真實(shí)的意思,我想用詞稍微犀利點(diǎn),請先做一下心理建設(shè)。
我不怎么懂 Java,就我淺薄的了解而言,如果你的公司、團(tuán)隊(duì)有很多傻逼,甚至你自己也是,業(yè)務(wù)上又正好可以用 Java 界的一些現(xiàn)成的框架、組件,那么用 Java 肯定是沒錯(cuò)的啦。它確實(shí)有一種魔力,讓你無論多傻逼,也絕對寫不出錯(cuò)得多么隱蔽、精妙無比的代碼;同時(shí)讓你無論多牛逼,也寫不出多么精彩絕倫、言簡意賅的代碼。Go 也有這種特質(zhì),甚至有些地方比起 Java 更有過之而不及。不信請看:
別人家的寫法:
r = f(p1, p2 != null ? p2 : p3)
$r = f($p1, $p2 ?? $p3)
Go 家的寫法:
var r someType
if p2 != nil {
r = f(p1, p2)
} else {
r = f(p1, p3)
}
為什么要設(shè)計(jì)成這樣?Go 爸爸說:你們有些人啊,會(huì)嵌套很多層 ?:
,導(dǎo)致代碼可讀性太差啦,于是禁止你們使用 ?:
,這是家法。在這里,作為熊孩子的代表,我來告訴大家怎樣寫出讓 Go 爸爸無語的代碼:
foo := 1
bar := 2
var foobar int
if foo > bar { if bar > 1 { foobar = 1 } else if bar < 0 { foobar = 2 } else { foobar = 3 } } else { if foo >= 3 { foobar = 4 } else { foobar = 5 } }
怎么樣?可讀性差不差?
看到了吧,這種傻逼是防不住的,他愿意把 ?: 嵌套好多層,它同樣可能會(huì)把 if else
嵌套好多層。有素質(zhì)的人會(huì)怎么做?遇到 ?:
嵌套太多立馬拆成 if else
。所以結(jié)論是,即使去掉 ?:
,傻逼還是傻逼,但是正常的人寫代碼就會(huì)很啰嗦;支持 ?:
,傻逼還是傻逼,正常人用起來爽。要知道一層 ?: 的場景占所有 ?:
場景的比例還是很高的吧。我覺得可以這樣,Go 爸爸可以統(tǒng)計(jì)一些工業(yè)級代碼庫的 ?:
嵌套層數(shù),作為數(shù)據(jù)支撐(比如自家 Chrome 里一層 ?:
占 95%,兩層占 4.9),然后再在語言層面只支持一層 ?:
,編譯參數(shù)可選打開兩層,不支持兩層以上。這就功在千秋了。
除了 不支持 ?:
,Go 爸爸還有很多這樣的設(shè)計(jì),隨便舉幾個(gè)例子:
- 不支持默認(rèn)參數(shù)
- 不支持運(yùn)算符重載
- 不提供 goroutine id(以及 gls、可重入鎖)
特別是第三點(diǎn),也是這種思路,因?yàn)槟銈兛赡軙?huì)濫用,所以我不提供。類似這種“爸爸思路”,是我今天要噴的最大噴點(diǎn)。前兩點(diǎn)也許是抄 Java 的,不怪 Go 爸爸。
綜上,Go 爸爸通過扼殺一些基本語法或者一些基礎(chǔ)信息,來防止傻逼干壞事,同時(shí)讓正常人用起來很啰嗦,同時(shí)還可能防止不了傻逼干壞事。這跟 Java 通過不提供高級語法來防止傻逼干壞事是師出同門啊,而且他們正好都能寫網(wǎng)絡(luò)服務(wù)程序,你說它們像不像?
然而,Go 爸爸也有精分的時(shí)候,它居然發(fā)明語法糖了耶!比如 if
可以執(zhí)行一個(gè)句句。單就這個(gè)語法而言,我的態(tài)度是中立偏贊。贊是贊 Go 爸爸確實(shí)用過心了,某些時(shí)候挺方便,還能縮小變量作用域;不過這個(gè)總歸是可有可無的,畢竟換一行寫也不會(huì)死,要變量作用域加個(gè)大括號就行。
小語法方面倒是有個(gè)亮點(diǎn),那就是 switch 的隱式 break、顯式 fallthrough 處理。不多展開了。
除了防傻逼,Go 爸爸還有一個(gè)思路,就是只許州官放火,不許百姓點(diǎn)燈。有兩個(gè)語法點(diǎn)——
- 泛型
- 逗號ok斷言
先說泛型吧。不支持泛型其實(shí)我挺能理解的,因?yàn)樗_實(shí)比 ?:
復(fù)雜多了,傻逼用不起,?:
都沒有,怎么可能會(huì)有泛型呢。然而 Go 爸爸有特權(quán)呀,它的 map、chan 可都是泛型的哦。但是你要寫一個(gè)泛型的語法結(jié)構(gòu)的話,對不起沒有。
再說逗號ok斷言,同樣 Go 爸爸要得起,我們要不起。其實(shí)我更想要一個(gè)這樣的語法:當(dāng)返回值是 xxx, ok 或者 xxx, err 的時(shí)候,我如果用一個(gè)返回值接,那么就返回第一個(gè),以便鏈?zhǔn)秸{(diào)用,同時(shí) !ok 或者 err != nil 的時(shí)候 panic。
以上兩小點(diǎn)雖然是在噴,不過還好啦。無所謂的。下面講幾個(gè)大的方面。
代碼組織
我特別贊賞 Go 對于 package 級嚴(yán)格的循環(huán)依賴檢查。然而如果加上其他規(guī)則:
- 一個(gè)目錄一個(gè) package
- 不同路徑下的同名目錄也是不同 package
- go 代碼無法拆成 .h、.cpp
實(shí)際可操作性就會(huì)非常差。要拆 package,就要把依賴關(guān)系梳理得特別嚴(yán)格,半點(diǎn)不得馬虎。這對工一般的程代碼來說是個(gè)極大的挑戰(zhàn)。
我更傾向于做成函數(shù)級循環(huán)依賴檢查,或者不限制(畢竟遞歸函數(shù)也是要支持的嘛)。
這部分,中立偏噴,偏噴是因?yàn)?Go 爸爸用了我的小名 internal。
OOP
我特別贊賞 Go 對于 OOP 泛濫成災(zāi)的思考與探索,以及對于終結(jié)這陣 Java 帶來的不正之風(fēng)的決心。怎么可能萬物都是 class 呢。但同時(shí),Go 還是有點(diǎn)矯枉過正的,如果我需要利用傳統(tǒng)的 OOP 來搞事情,就非常麻煩,你甚至都無法寫出一個(gè)框架來。你只能寫庫讓別人用。雖然我也不喜歡框架,但有的時(shí)候是需要框架的。
defer 非常切中痛點(diǎn),特別解決一堆錯(cuò)誤 return 外加資源釋放的問題。相比之下C 里只能用 goto,C++ 本身不支持但可以玩出 LOKI_ON_BLOCK_EXIT 或者 BOOST_SCOPE_EXIT。defer 一舉解決問題。(要是能再增加命名 defer 以及撤銷 defer 的功能就更好了。沒錯(cuò),你也許看出來了,我覺得 LOKI_ON_BLOCK_EXIT 是最完美的方案。)
雖然 defer 很好,但不意味著析構(gòu)就沒用武之地了。理想的情況是,析構(gòu)、多態(tài)、defer 都要有……
這部分我的態(tài)度是中立。
錯(cuò)誤處理
終于要點(diǎn)贊了。錯(cuò)誤處理是在我看來 go 完勝的地方,恰到好處地處理問題,又防止濫用。也矯正 Java 帶來的歪風(fēng)邪氣。
Java 的設(shè)計(jì),讓人不得不用異常來處理業(yè)務(wù)。甚至 Java 自己還幫我們分好類了:一種是不是異常的異常,用來處理業(yè)務(wù);另一種是真的異常。一些用慣 Java 的傻逼跑到 C++、PHP、Python 里亂拉屎,到處是 try catch。
Go 爸爸一聲令下,萬籟俱寂。
goroutine
最后不得不說說 gorouthine,畢竟是賣點(diǎn)嘛。我的態(tài)度中立偏贊。贊是因?yàn)檫@是一種太有創(chuàng)意的方案,居然想在在語言層面解決多線程、并發(fā)問題;不過我還是覺得這更多的是應(yīng)用層面的問題,做到官方庫里會(huì)更好,而不是做成語法。
總結(jié)
剛開始用 Go 的時(shí)候,特別亮眼,簡直處處是亮點(diǎn),然后越接觸越討厭,一點(diǎn)也不耐看……看得出來,設(shè)計(jì)者糅合了 C、python、Java 的一些特性,并融入了自己的獨(dú)特的理解。Go的設(shè)計(jì)者真的特別特立獨(dú)行且堅(jiān)持己見,一些我喜歡的特性因?yàn)樗麄兊膱?jiān)持而存在下來,一些我討厭的特性也因?yàn)樗麄兊膱?jiān)(Gu)持(Zhi)而不能有所改觀。就這樣的 Go,想代替 C 作為系統(tǒng)語言,是沒戲的;想在網(wǎng)絡(luò)服務(wù)有一番作為,搶 Java 的份額,或許是有機(jī)會(huì)的,不過最多只能搶 Java 的,連 C# 的都搶不了,C++、PHP 更搶不了。
嗯,除了特定的不得不用的場合,反正我是不會(huì)特意用 Go 的。
2019,新年快樂!
posted @
2020-09-20 14:16 溪流 閱讀(4468) |
評論 (0) |
編輯 收藏
(原發(fā)于 GitHub Pages,2018-10-13 13:51:09)
兩年前我從一名光榮的C++程序員專業(yè)為PHP程序員以后,告別了世界第一IDE Visual Studio,改用當(dāng)時(shí)覺得特別難用的 PHPStorm。用了這么久以后,覺得IntelliJ系列雖比不上VS,大概也有世界第二吧,至少比eclipse強(qiáng)太多。除了慢大概也沒啥好吐槽的了。
最近又要寫Go又要寫PHP,最開始PHPStorm和GoLand一起用,后來想,用兩個(gè)渠道包干嘛呢,還使用他們家的主打產(chǎn)品Idea吧。。。
雖然說程序員一般是要用英文版的,不管是為了實(shí)用還是為了裝逼。但為了更多人能入門,我們發(fā)起一個(gè)開源項(xiàng)目來漢化吧,在 https://github.com/Streamlet/ideaLocalization,歡迎有志之士加入。
我們主要就是翻譯 resources.jar。代碼框架是這樣的,resources\en 是原文件解壓后的,resources\zh-CN是復(fù)制了一份resources\en,我們只要在resources\zh-CN里面就地改動(dòng)即可。
build.py會(huì)把散著的文件們打包成resources.jar。jar里的properties文件里,如果有中文,不能直接是UTF或GBK,必須轉(zhuǎn)成\uXXXX的寫法。這個(gè)build.py會(huì)幫忙轉(zhuǎn),因此resources\zh-CN里直接寫中文(UTF-8)就好。
就是發(fā)起個(gè)項(xiàng)目意思意思,估計(jì)我是沒時(shí)間翻譯的……^_^
當(dāng)前進(jìn)度
已完成:
使用方法
- 獲取語言包。您可以:
- 直接從 release 列表下載 resource_zh_CN.jar
- clone 本項(xiàng)目,運(yùn)行本項(xiàng)目根目錄的 build.py 來生成 resource_zh_CN.jar
- 將語言包復(fù)制到 idea 安裝目錄的 lib 目錄下,復(fù)制到 lib 目錄下,復(fù)制到 lib 目錄下
- 重啟 idea
注意事項(xiàng)
- 取決于不同操作系統(tǒng),您可能需要將系統(tǒng)的界面語言設(shè)置為簡體中文(zh-CN)才能生效。
- 本項(xiàng)目目前只針對 idea,對于 jetBrains 的其他產(chǎn)品尚未做適配,理論上可能支持或部分支持,請自行嘗試。
加入我們
本項(xiàng)目誠邀您的加入,歡迎您貢獻(xiàn)自己的力量。
- 您只需原地修改 resources 下的文件即可,可以在空閑的時(shí)候修改一個(gè)文件、甚至一行
- 本項(xiàng)目謝絕直接的自動(dòng)翻譯,但不介意您個(gè)人使用自動(dòng)翻譯進(jìn)行某種形式的協(xié)助,但最終請您進(jìn)行人工核對
- 本項(xiàng)目遵循軟件行業(yè)通用的翻譯規(guī)范,同時(shí)對標(biāo) Visual Studio 的翻譯。請自行體會(huì)。下面會(huì)羅列一些細(xì)則。
分支說明
- dev_build_script: 專門修改構(gòu)建腳本
- dev_readme:專門修改 readme
- original_resources_tracker: 英文資源文件
- dev_translate:翻譯
合并策略
- dev_build_script 每次修改并測試通過后合入 master
- dev_readme 每次修改穩(wěn)定后合入 master
- original_resources_tracker 每次更新資源后打 tag,合入 master
- dev_translate 經(jīng)常性地從 master 合并新的提交
- 當(dāng) dev_translate 穩(wěn)定后,從 dev_translate 進(jìn)行發(fā)布
- dev_translate 在發(fā)布時(shí)必須處于對 master 可 Fast-Forward 狀態(tài)
- dev_translate 發(fā)布之后 master Fast-Forward 到 dev_translate
協(xié)作方式
- Fork 版本庫,在 dev_translate 上修改,提交 pull request 回來
- 未來時(shí)機(jī)成熟的話,成立一個(gè) github 上的 oraganization,屆時(shí)加入
翻譯規(guī)范
- 標(biāo)點(diǎn):行文中一般使用中文半角,某些形式文案中可能需要用英文半角符號
- 需要打開對話框操作的菜單項(xiàng),使用英文半角的三個(gè)點(diǎn)(“...”)表示
- 菜單項(xiàng)/按鈕后的快捷鍵兩側(cè)使用英文半角括號
- 中英文混排:中文和英文之間需要使用一個(gè)半角空格進(jìn)行分隔
- 菜單項(xiàng)/按鈕的快捷鍵:放在文案之后,如“文件(<u>F</u>)”
詞匯表
英文 | 推薦翻譯 | 不推薦的翻譯 |
View | 視圖 | 查看 |
Build | 生成 | 構(gòu)建 |
posted @
2020-09-20 14:00 溪流 閱讀(2240) |
評論 (2) |
編輯 收藏
4月份就有人留言舊微軟拼音恢復(fù)工具不支持Win10 1803了,我自己也遇到了,但因?yàn)闆]時(shí)間搞,勉為其難使用了詞組模式的微軟拼音幾個(gè)月,終于在八月份抽個(gè)空研究了下,解決了。
這次是因?yàn)樯当拼笪④浉牧?System32\IME\shared 里的東西,導(dǎo)致舊系統(tǒng)拷過來的文件與 System32\IME\shared 的東西不兼容了。解決方式很暴力:從以前的版本復(fù)制 System32\IME\shared 過來。
下載:https://www.streamlet.org/software/mspyforever/
(原發(fā)于 GitHub Pages,2018-10-13 13:36:04)
posted @
2020-09-20 13:53 溪流 閱讀(609) |
評論 (0) |
編輯 收藏