聲明
- 這是一套幫助初學(xué)者從0到1學(xué)習(xí)go語言的開源教程粟判,致力于打造最完整豌习、最強(qiáng)悍尾膊、最有深度的Go語言學(xué)習(xí)體系
- 我希望這套課程能夠涵蓋Go語言的所有體系斩松、并致力于用大量的案例來詮釋其用法
- 鑒于作者水平有限瞻凤,真誠地希望能夠集所有人的智慧憨攒,完善此項(xiàng)目,鏈接附后
簡介
- Go(又稱Golang)是Google開發(fā)的一種靜態(tài)強(qiáng)類型阀参、編譯型肝集、并發(fā)型,并具有垃圾回收功能的編程語言
- Go的最初目標(biāo)是消除Google軟件開發(fā)的緩慢性和笨拙性蛛壳,從而使流程更具效率和可擴(kuò)展性杏瞻,更多的關(guān)注于軟件工程領(lǐng)域
- Go致力于解決當(dāng)代大型工程項(xiàng)目面臨的多核處理,網(wǎng)絡(luò)系統(tǒng)衙荐,海量計(jì)算集群捞挥、快速構(gòu)建等問題,Go在語言級別考慮并發(fā)問題,提供簡單高效的并發(fā)編程
- 羅伯特·格瑞史莫(Robert Griesemer)忧吟,羅勃·派克(Rob Pike)及肯·湯普遜(Ken Thompson)于2007年9月開始設(shè)計(jì)Go砌函,稍后Ian Lance Taylor、Russ Cox加入項(xiàng)目
- Go是基于Inferno操作系統(tǒng)所開發(fā)的
- Go于2009年11月正式宣布推出溜族,成為開放源代碼項(xiàng)目讹俊,支持Linux、macOS煌抒、Windows等操作系統(tǒng)
- 在2016年仍劈,Go被軟件評價公司TIOBE 選為“TIOBE 2016 年最佳語言”
- 很多重要的開源項(xiàng)目都是使用Go語言開發(fā)的,其中包括 Docker寡壮、Go-Ethereum耳奕、Thrraform绑青、Kubernetes、etcd屋群、hyperledger闸婴、tidb
基本語言的歷史
- 1960年 Ken Thompson(肯.湯普森) 發(fā)明了B語言
- 1972年 Dennis Ritchie(丹尼斯·里奇)發(fā)明了C語言
- 1982年 Bjarne Stroustrup(本賈尼)發(fā)明了C++語言
- 1989年 Guido von Rossum 發(fā)明了Python語言
- 1995年SUN公司發(fā)明了Java語言
- 2007年Go語言誕生
- 2009年的11月對外正式發(fā)布
Go語言創(chuàng)始人
對語言進(jìn)行評估時,明白設(shè)計(jì)者的動機(jī)以及語言要解決的問題很重要芍躏。Go語言出自 Ken Thompson 和 Rob Pike邪乍、Robert Griesemer 之手,他們都是計(jì)算機(jī)科學(xué)領(lǐng)域的重量級人物对竣。
- Ken Thompson
貝爾實(shí)驗(yàn)室 Unix 團(tuán)隊(duì)成員庇楞,C語言、Unix 和 Plan 9 的創(chuàng)始人之一否纬,在 20 世紀(jì) 70 年代吕晌,設(shè)計(jì)并實(shí)現(xiàn)了最初的 UNIX 操作系統(tǒng),僅從這一點(diǎn)說临燃,他對計(jì)算機(jī)科學(xué)的貢獻(xiàn)怎么強(qiáng)調(diào)都不過分睛驳。他還與 Rob Pike 合作設(shè)計(jì)了 UTF-8 編碼方案 - Rob Pike
Go語言項(xiàng)目總負(fù)責(zé)人,貝爾實(shí)驗(yàn)室 Unix 團(tuán)隊(duì)成員膜廊,除幫助設(shè)計(jì) UTF-8 外乏沸,還幫助開發(fā)了分布式多用戶操作系統(tǒng) Plan 9、Inferno 操作系統(tǒng)和 Limbo 編程語言爪瓜,并與人合著了《The Unix Programming Environment》蹬跃,對 UNIX 的設(shè)計(jì)理念做了正統(tǒng)的闡述 - Robert Griesemer
就職于 Google,參與開發(fā) Java HotSpot 虛擬機(jī)铆铆,對語言設(shè)計(jì)有深入的認(rèn)識蝶缀,并負(fù)責(zé) Chrome 瀏覽器和 Node.js 使用的 Google V8 JavaScript 引擎的代碼生成部分
go語言的繼承
Go語言有時候被描述為“C類似語言”,或者是“21世紀(jì)的C語言”
Go從C語言繼承了相似的表達(dá)式語法薄货、控制流結(jié)構(gòu)扼劈、基礎(chǔ)數(shù)據(jù)類型、調(diào)用參數(shù)傳值菲驴、指針等思想
Go繼承了C語言一直所看中的編譯后機(jī)器碼的運(yùn)行效率以及和現(xiàn)有操作系統(tǒng)的無縫適配
Go語言的家族樹中還有其它的祖先荐吵。其中一個有影響力的分支來自Niklaus Wirth所設(shè)計(jì)的Pascal語言
Modula-2語言激發(fā)了包的概念,然后Oberon語言摒棄了模塊接口文件和模塊實(shí)現(xiàn)文件之間的區(qū)別赊瞬。第二代的Oberon-2語言直接影響了包的導(dǎo)入和聲明的語法先煎,還有Oberon語言的面向?qū)ο筇匦运峁┑姆椒ǖ穆暶髡Z法等
Go語言的另一支祖先,帶來了Go語言區(qū)別其他語言的重要特性巧涧,靈感來自于貝爾實(shí)驗(yàn)室的Tony Hoare于1978年發(fā)表的鮮為外界所知的關(guān)于并發(fā)研究的基礎(chǔ)文獻(xiàn)順序通信進(jìn)程(communicating sequential processes薯蝎,縮寫為CSP)
在CSP中,程序是一組中間沒有共享狀態(tài)的平行運(yùn)行的處理過程谤绳,它們之間使用管道進(jìn)行通信和控制同步占锯。不過Tony Hoare的CSP只是一個用于描述并發(fā)性基本概念的描述語言袒哥,并不是一個可以編寫可執(zhí)行程序的通用編程語言
Rob Pike和其他人開始不斷嘗試將CSP引入實(shí)際的編程語言中。他們第一次嘗試引入CSP特性的編程語言叫Squeak消略,是一個提供鼠標(biāo)和鍵盤事件處理的編程語言堡称,它的管道是靜態(tài)創(chuàng)建的
然后是改進(jìn)版的Newsqueak語言,提供了類似C語言語句和表達(dá)式的語法和類似Pascal語言的推導(dǎo)語法艺演。Newsqueak是一個帶垃圾回收的純函數(shù)式語言却紧,它再次針對鍵盤、鼠標(biāo)和窗口事件管理胎撤。在Newsqueak語言中管道是動態(tài)創(chuàng)建的晓殊,屬于第一等公民,可以保存到變量中
在Plan9操作系統(tǒng)中,這些優(yōu)秀的想法被吸收到了一個叫Alef的編程語言中伤提。Alef試圖將Newsqueak語言改造為系統(tǒng)編程語言巫俺,但是因?yàn)槿鄙倮厥諜C(jī)制而導(dǎo)致并發(fā)編程很痛苦
注:在Aelf之后還有一個叫Limbo的編程語言,Go語言從其中借鑒了很多特性肿男。具體請參考Pike的講稿:http://talks.golang.org/2012/concurrency.slide#9
Go語言的其他的一些特性零散地來自于其他一些編程語言介汹;比如iota語法是從APL語言借鑒,詞法作用域與嵌套函數(shù)來自于Scheme語言和其他很多語言
Go中也有很多創(chuàng)新的設(shè)計(jì)次伶,比如Go語言的切片為動態(tài)數(shù)組提供了有效的隨機(jī)存取的性能痴昧,還有Go語言新發(fā)明的defer語句
go語言的特點(diǎn)
所有的編程語言都反映了語言設(shè)計(jì)者對編程哲學(xué)的反思稽穆,通常包括之前的語言所暴露的一些不足地方的改進(jìn)冠王。
簡潔
Go項(xiàng)目是在Google公司維護(hù)超級復(fù)雜的幾個軟件系統(tǒng)遇到的一些問題的反思(但是這類問題絕不是Google公司所特有的)
正如Rob Pike所說,“軟件的復(fù)雜性是乘法級相關(guān)的”舌镶,通過增加一個部分的復(fù)雜性來修復(fù)問題通常將慢慢地增加其他部分的復(fù)雜性
通過增加功能柱彻、選項(xiàng)、配置是修復(fù)問題的最快的途徑餐胀,但是這很容易讓人忘記簡潔的內(nèi)涵哟楷,卽使從長遠(yuǎn)來看,簡潔依然是好軟件的關(guān)鍵因素
簡潔的設(shè)計(jì)需要在工作開始的時候舍棄不必要的想法否灾,并且在軟件的生命周期內(nèi)嚴(yán)格區(qū)別好的改變或壞的改變卖擅。通過足夠的努力,一個好的改變可以在不破壞原有完整概念的前提下保持自適應(yīng)
而一個壞的改變則不能達(dá)到這個效果墨技,它們僅僅是通過膚淺的和簡單的妥協(xié)來破壞原有設(shè)計(jì)的一致性惩阶。只有通過簡潔的設(shè)計(jì),才能讓一個系統(tǒng)保持穩(wěn)定扣汪、安全和持續(xù)的進(jìn)化
附帶了相關(guān)的工具和標(biāo)準(zhǔn)庫
沒有隱式的數(shù)值轉(zhuǎn)換
沒有構(gòu)造函數(shù)和析構(gòu)函數(shù)
沒有運(yùn)算符重載
沒有默認(rèn)參數(shù)
沒有繼承
沒有泛型(go2中考慮加入)
沒有異常断楷,即沒有與錯誤處理相關(guān)的控制結(jié)構(gòu)
沒有宏
沒有函數(shù)修飾
沒有線程局部存儲。
沒有指針運(yùn)算
沒有類型別名
數(shù)組邊界總是受到檢查
基本特性
自動垃圾回收
包管理
函數(shù)作為一等公民
系統(tǒng)調(diào)用接口
只讀的UTF8字符串
函數(shù)多返回值
匿名函數(shù)和閉包
反射
靜態(tài)鏈接
嚴(yán)格的依賴規(guī)范
CSP并發(fā)編程
Goroutine協(xié)程
接口類型
向后兼容
Go語言本身是成熟和穩(wěn)定的崭别,而且承諾保證向后兼容:用之前的Go語言編寫程序可以用新版本的Go語言編譯器和標(biāo)準(zhǔn)庫直接構(gòu)建而不需要修改代碼
類型系統(tǒng)
相比較于js冬筒、python恐锣,Go語言的類型系統(tǒng)避免動態(tài)語言中那些粗心的類型錯誤。但是Go語言的類型系統(tǒng)相比傳統(tǒng)的強(qiáng)類型語言又要簡潔很多舞痰,雖然有時候這會導(dǎo)致一個“無類型”的抽象類型的概念
Go語言程序員并不需要像C++或Haskell程序員那樣糾結(jié)于具體類型的安全屬性土榴。在實(shí)踐中Go語言簡潔的類型系統(tǒng)給了程序員帶來了更多的安全性和更好的運(yùn)行時性能
Go語言遵循當(dāng)代計(jì)算機(jī)系統(tǒng)設(shè)計(jì)的原則,特別是局部的重要性匀奏。Go的內(nèi)置數(shù)據(jù)類型和大多數(shù)的標(biāo)準(zhǔn)數(shù)據(jù)結(jié)構(gòu)都經(jīng)過精心設(shè)計(jì)而避免顯式的初始化或隱式的構(gòu)造函數(shù)鞭衩,因此內(nèi)存分配和內(nèi)存初始化代碼被隱藏在庫代碼中了
Go語言的聚合類型(結(jié)構(gòu)體和數(shù)組)可以直接操作它們的元素,只需要更少的存儲空間娃善、更少的內(nèi)存分配论衍,而且指針操作比其他間接操作的語言也更有效率
并發(fā)支持
由于現(xiàn)代計(jì)算機(jī)是一個并行的機(jī)器,Go語言提供了基于CSP的并發(fā)特性支持聚磺。Go語言的動態(tài)棧使得輕量級線程goroutine的初始椗魈ǎ可以很小,因此創(chuàng)建一個goroutine的代價很小瘫寝,創(chuàng)建百萬級的goroutine完全是可行的蜒蕾。
Go并發(fā)的座右銘:不要通過共享內(nèi)存進(jìn)行通信,而要通過通信共享內(nèi)存(Don't communicate by sharing memory, share memory by communicating)
自動垃圾回收機(jī)制
對于系統(tǒng)語言焕阿,垃圾回收可能是一個有爭議的功能
Go沒有顯式的內(nèi)存釋放操作:分配的內(nèi)存返回池的唯一方法是通過垃圾回收器咪啡。
內(nèi)存管理對語言在實(shí)踐中的工作方式具有深遠(yuǎn)的影響。在C和C++中暮屡,太多的編程工作花費(fèi)在內(nèi)存分配和釋放上
由于垃圾回收機(jī)制撤摸,語言更易于使用。
垃圾回收會帶來巨大的成本:常規(guī)開銷褒纲,延遲和實(shí)現(xiàn)的復(fù)雜性
知識淵博的程序員可以限制收集器所承受的壓力准夷,從而提高性能。(此外莺掠,Go安裝附帶了用于研究正在運(yùn)行的程序的動態(tài)內(nèi)存性能的良好工具)
自動垃圾回收算法是一個持續(xù)跟新的過程衫嵌、活躍的開發(fā)領(lǐng)域
強(qiáng)大的標(biāo)準(zhǔn)庫與規(guī)范
Go語言的標(biāo)準(zhǔn)庫,提供了清晰的構(gòu)建模塊和公共接口彻秆,包含I/O操作楔绞、文本處理、圖像唇兑、密碼學(xué)酒朵、網(wǎng)絡(luò)和分布式應(yīng)用程序等,并支持許多標(biāo)準(zhǔn)化的文件格式和編解碼協(xié)議
庫和工具使用了大量的約定來減少額外的配置和解釋幔亥,從而最終簡化程序的邏輯耻讽,而且每個Go程序結(jié)構(gòu)都是如此的相似,因此Go程序也很容易學(xué)習(xí)
Go語言自帶工具構(gòu)建Go語言項(xiàng)目只需要使用文件名帕棉、標(biāo)識符名稱以及少量的注釋確定所有的庫针肥、可執(zhí)行文件饼记、測試、基準(zhǔn)測試慰枕、案例具则、以及特定于平臺的變量、項(xiàng)目的文檔等具帮;Go語言源代碼本身就包含了構(gòu)建規(guī)范
開源,活躍的社區(qū)
組成而不是繼承
Go采用一種不尋常的方法來進(jìn)行面向?qū)ο蟮木幊蹋ń涌冢┎├撸试S有相同方法的任何類型繼承,而不僅是類
Go沒有任何形式的基于類型的繼承,這意味著沒有類型層次結(jié)構(gòu)
這是一個故意的設(shè)計(jì)選擇,盡管類型層次結(jié)構(gòu)已用于構(gòu)建許多成功的軟件蜂厅,但Go認(rèn)為該模型已被過度使用
Go語言的優(yōu)勢
學(xué)習(xí)曲線容易匪凡,語法簡單清晰
單就類型和規(guī)則而言,Go 與 C99掘猿、C11 相似之處頗多病游,這也是Go語言被冠以“NextC”名號的重要原因。
Go語言的語法規(guī)則嚴(yán)謹(jǐn)稠通,沒有歧義衬衬,更沒什么黑魔法變異用法。
任何人寫出的代碼都基本一致改橘,這使得Go語言簡單易學(xué)滋尉。放棄部分“靈活”和“自由”,換來更好的維護(hù)性
強(qiáng)大的標(biāo)準(zhǔn)庫和工具鏈
完整的工具鏈對于日常開發(fā)極為重要飞主。Go 在此做得相當(dāng)不錯狮惜,無論是編譯、格式化既棺、錯誤檢查讽挟、幫助文檔懒叛,還是第三方包下載丸冕、更新都有對應(yīng)的工具
內(nèi)置完整測試框架,其中包括單元測試薛窥、性能測試胖烛、代碼覆蓋率、數(shù)據(jù)競爭诅迷,以及用來調(diào)優(yōu)的 pprof佩番,這些都是保障代碼能正確而穩(wěn)定運(yùn)行的必備利器
可通過環(huán)境變量輸出運(yùn)行時監(jiān)控信息,尤其是垃圾回收和并發(fā)調(diào)度跟蹤罢杉,可進(jìn)一步幫助我們改進(jìn)算法趟畏,獲得更佳的運(yùn)行期表現(xiàn)
自動垃圾回收機(jī)制
垃圾回收一直是個難題。早年間滩租,Java 就因垃圾回收低效被嘲笑了許久赋秀,后來 Sun 連續(xù)收納了好多人和技術(shù)才發(fā)展到今天利朵。可即便如此猎莲,在 Hadoop 等大內(nèi)存應(yīng)用場景下绍弟,垃圾回收依舊捉襟見肘、步履維艱
相比 Java著洼,Go 面臨的困難要更多樟遣。因指針的存在,所以回收內(nèi)存不能做收縮處理身笤。幸好豹悬,指針運(yùn)算被阻止,否則要做到精確回收都難
每次升級液荸,垃圾回收器必然是核心組件里修改最多的部分屿衅。從并發(fā)清理,到降低 STW 時間莹弊,直到 Go 的 1.5 版本實(shí)現(xiàn)并發(fā)標(biāo)記涤久,逐步引入三色標(biāo)記和寫屏障等等,都是為了能讓垃圾回收在不影響用戶邏輯的情況下更好地工作
靜態(tài)鏈接
運(yùn)行時忍弛、依賴庫直接打包到可執(zhí)行文件內(nèi)部响迂,簡化了部署和發(fā)布操作,無須事先安裝運(yùn)行環(huán)境和下載諸多第三方庫編譯迅速
清晰的依賴關(guān)系
并發(fā)編程
在早期 CPU 都是以單核的形式順序執(zhí)行機(jī)器指令细疚。Go語言的祖先C語言正是這種順序編程語言的代表
隨著處理器技術(shù)的發(fā)展蔗彤,單核時代以提升處理器頻率來提高運(yùn)行效率的方式遇到了瓶頸,單核 CPU 發(fā)展的停滯疯兼,給多核 CPU 的發(fā)展帶來了機(jī)遇
現(xiàn)代計(jì)算機(jī)都擁有多個核然遏,但是大部分編程語言都沒有有效的工具讓程序可以輕易利用這些資源。編程時需要寫大量的線程同步代碼來利用多個核吧彪,很容易導(dǎo)致錯誤
Go語言正是在多核和網(wǎng)絡(luò)化的時代背景下誕生的原生支持并發(fā)的編程語言待侵。Go語言從底層原生支持并發(fā),無須第三方庫姨裸,開發(fā)人員可以很輕松地在編寫程序時決定怎么使用 CPU 資源
Goroutine 是 Go 最顯著的特征
Go語言的并發(fā)是基于 goroutine 的秧倾,goroutine 類似于線程,但并非線程傀缩∧窍龋可以將 goroutine 理解為一種虛擬線程。Go語言運(yùn)行時會參與調(diào)度 goroutine赡艰,并將 goroutine 合理地分配到每個 CPU 中售淡,最大限度地使用 CPU 性能
Go用類協(xié)程的方式來處理并發(fā)單元,卻又在運(yùn)行時層面做了更深度的優(yōu)化處理。這使得語法上的并發(fā)編程變得極為容易
無須處理回調(diào)揖闸,無須關(guān)注線程切換苦掘,僅一個關(guān)鍵字,簡單而自然
搭配 channel楔壤,實(shí)現(xiàn) CSP 模型鹤啡。將并發(fā)單元間的數(shù)據(jù)耦合拆解開來,各司其職蹲嚣,這對所有糾結(jié)于內(nèi)存共享递瑰、鎖粒度的開發(fā)人員都是一個可期盼的解脫
內(nèi)存分配
Go 選擇了 tcmalloc,它本就是為并發(fā)而設(shè)計(jì)的高性能內(nèi)存分配組件
刨去因配合垃圾回收器而修改的內(nèi)容隙畜,內(nèi)存分配器完整保留了 tcmalloc 的原始架構(gòu)抖部。使用 cache 為當(dāng)前執(zhí)行線程提供無鎖分配,多個 central 在不同線程間平衡內(nèi)存單元復(fù)用
heap 則管理著大塊內(nèi)存议惰,用以切分成不同等級的復(fù)用內(nèi)存塊慎颗。快速分配和二級內(nèi)存平衡機(jī)制言询,讓內(nèi)存分配器能優(yōu)秀地完成高壓力下的內(nèi)存管理任務(wù)
Go語言擅長的領(lǐng)域
- Go語言主要用作服務(wù)器端開發(fā)俯萎,適合于多人周期較長的大型軟件和支持云計(jì)算的網(wǎng)絡(luò)服務(wù)
- 在服務(wù)器編程方面,Go語言適合處理日志运杭、中間件夫啊、數(shù)據(jù)打包、虛擬機(jī)處理辆憔、文件系統(tǒng)撇眯、分布式系統(tǒng)、數(shù)據(jù)庫代理等
- 網(wǎng)絡(luò)編程方面虱咧,Go語言廣泛應(yīng)用于 Web 應(yīng)用熊榛、API 應(yīng)用、下載應(yīng)用等
- 此外腕巡,Go語言還可用于內(nèi)存數(shù)據(jù)庫和云平臺領(lǐng)域玄坦,目前國外很多云平臺都是采用 Go 開發(fā)
- 由于Go垃圾回收犧牲了一些性能,因此其不適合做操作系統(tǒng)編程以及對速度要求極致的程序逸雹,不適合直接處理數(shù)據(jù)分析與計(jì)算
使用Go語言的公司
Google
作為創(chuàng)造了Go語言的 google 公司营搅,當(dāng)然會力挺Go語言了云挟。Google 有很多基于 Go 開發(fā)的開源項(xiàng)目梆砸,比如 kubernets,docker园欣,大家可以參考《哪些項(xiàng)目使用Go語言開發(fā)》一節(jié)了解更多的Go語言開源項(xiàng)目
Facebook
Facebook 也在使用Go語言帖世,為此他們還專門在 Github 上建立了一個開源組織 facebookgo。大家可以通過 https://github.com/facebookgo 訪問查看 facebook 開源的項(xiàng)目,其中最具代表性的就是著名平滑重啟工具 grace
騰訊
騰訊在 15 年就已經(jīng)做了 Docker 萬臺規(guī)模的實(shí)踐日矫。因?yàn)轵v訊主要的開發(fā)語言是 C/C++ 赂弓,所以在使用Go語言方面會方便很多,也有很多優(yōu)勢哪轿,不過日積月累的 C/C++ 代碼很難改造盈魁,也不敢動,所以主要在新業(yè)務(wù)上嘗試使用 Go
百度
百度主要在運(yùn)維方面使用到了Go語言窃诉,比如百度運(yùn)維的一個 BFE 項(xiàng)目杨耙,主要負(fù)責(zé)前端流量的接入,其次就是百度消息通訊系統(tǒng)的服務(wù)器端也使用到了Go語言
七牛云
七牛云算是國內(nèi)第一家選Go語言做服務(wù)端的公司飘痛。早在 2011 年珊膜,當(dāng)Go語言的語法還沒完全穩(wěn)定下來的情況下晨川,七牛云就已經(jīng)選擇將 Go 作為存儲服務(wù)端的主體語言
京東
京東云消息推送系統(tǒng)丈牢、云存儲,以及京東商城的列表頁等都是使用Go語言開發(fā)的
小米
小米對Go語言的支持骡尽,在于運(yùn)維監(jiān)控系統(tǒng)的開源塑猖,它的官方網(wǎng)址是 http://open-falcon.org/竹祷。此外,小米互娛羊苟、小米商城溶褪、小米視頻、小米生態(tài)鏈等團(tuán)隊(duì)都在使用Go語言
360
360 對Go語言的使用也不少践险,比如開源的日志搜索系統(tǒng) Poseidon猿妈,大家可以通過 https://github.com/Qihoo360/poseidon 查看,還有 360 的推送團(tuán)隊(duì)也在使用Go語言
除了上面提到的巍虫,還有很多公司開始嘗試使用Go語言彭则,比如美團(tuán)、滴滴占遥、新浪等俯抖。
Go語言吉祥物
Go語言有一個吉祥物,在會議瓦胎、文檔頁面和博文中芬萍,大多會包含下圖所示的 Go Gopher,這是才華橫溢的插畫家 Renee French 設(shè)計(jì)的搔啊,她也是 Go 設(shè)計(jì)者之一 Rob Pike 的妻子柬祠。