Go In Action --- struct淆两、方法

go元是一種靜態(tài)類型的編程語言。這意味著拂酣,編譯器需要在編譯時(shí)知曉程序里每個(gè)值的類型秋冰。如果提前知道類型信息,編譯器就可以確保程序合理地使用值婶熬。這有助于減少潛在的內(nèi)存異常和bug丹莲,并且使編譯器有機(jī)會對代碼進(jìn)行一些性能優(yōu)化,提高執(zhí)行效率尸诽。

用戶定義的類型

go語言中最常用的方法是使用關(guān)鍵字struct
聲明一個(gè)新的結(jié)構(gòu)類型甥材,以關(guān)鍵字type開始,之后是新類型的名字性含,最后是關(guān)鍵字struct洲赵。

// user 在程序里定義一個(gè)用戶類型
type user struct {
    name       string
    email      string
    ext        int
    privileged bool
}

關(guān)鍵字var創(chuàng)建了類型user,且名為bill的變量商蕴。
注:當(dāng)聲明一個(gè)變量時(shí)叠萍,該變量對應(yīng)的值總會被初始化。這個(gè)值要么用指定的值初始化绪商,要么用零值做初始化苛谷。如這里的bill變量,其中的屬性如果是數(shù)值類型格郁,零值就是0腹殿;如果類型是字符串,零值就是空字符串例书;如果是布爾類型锣尉,零值是false。

//聲明user類型的變量
var bill user

聲明一個(gè)user類型變量决采,并使用非零值作為初始值自沧。符號:=表示短變量聲明操作符。主要負(fù)責(zé)兩件事:聲明一個(gè)變量树瞭,并初始化拇厢。

//聲明user類型的變量,并初始化所有字段
lisa := user {
    name : "Lisa",
    email : "lisa@email.com",
    ext : 123,
    privileged: true,
}

//另一種聲明并初始化的方式晒喷,不使用結(jié)構(gòu)字面量孝偎。
//但是要注意字段順序
baker := user{"Baker", "baker@email.com", 123, true}

使用其它自定義的結(jié)構(gòu)類型作為字段類型

//admin需要一個(gè)user類型作為管理者,并附加權(quán)限
type admin struct {
    person user
    level string
}

此時(shí)厨埋,當(dāng)聲明的字段有其它自定義的結(jié)構(gòu)類型時(shí)邪媳,初始化也會有一些不同捐顷。

    fred := admin{
        person: user{
            name: "Jon",
            email: "jon@email.com",
            ext: 12333,
            privileged: true,
        },
        level: "super",
    }
    log.Println("==================fred====================")
    log.Println(fred.level)
    log.Println(fred.person)
    //2017/08/13 22:39:08 ==================fred====================
    //2017/08/13 22:39:08 super
    //2017/08/13 22:39:08 {Jon jon@email.com 12333 true}

方法

方法能給用戶定義的類型添加新的行為荡陷。方法實(shí)際上也是函數(shù)雨效,只是在聲明的時(shí)候,在關(guān)鍵字func和方法名之間增加了一個(gè)參數(shù)废赞。

type user struct {
    name  string
    email string
}

// notify 使用值接收者實(shí)現(xiàn)一個(gè)方法
func (u user) notify() {
    fmt.Printf("Sending user Email To %s<%s>\n", u.name, u.email)
}

// changeEmail 使用指針接收者實(shí)現(xiàn)了一個(gè)方法
func (u *user) changeEmail(email string) {
    u.email = email
}

func UserMethod() {
    //user類型的值可以調(diào)用使用值接收者聲明的方法
    bill := user{"Bill", "bill@email.com"}
    bill.notify()  //Sending user Email To Bill<bill@email.com>

    //指向user類型的指針也可以調(diào)用使用值接收者聲明的方法
    lisa := &user{"Lisa", "lisa@email.com"}
    lisa.notify()  //Sending user Email To Lisa<lisa@email.com>

    //user類型的值可以調(diào)用使用指針接收者聲明的方法
    bill.changeEmail("billNew@email.com")
    bill.notify()  //Sending user Email To Bill<billNew@email.com>

    //指向user類型值的指針可以調(diào)用使用指針接收者聲明的方法
    lisa.changeEmail("lisaNew@email.com")
    lisa.notify()  //Sending user Email To Lisa<lisaNew@email.com>
}

到這徽龟,其實(shí)可以看出這和Java當(dāng)中的class類聲明對象和方法大同小異。但是go語言中多了接收者這個(gè)概念唉地,且分為兩種:

  1. 值接收者
  2. 指針接收者

代碼剖析

  1. 值接收者聲明方法與調(diào)用
//notify方法的接收者据悔,被聲明為user類型的值
//使用值接收者聲明方法,調(diào)用時(shí)耘沼,會使用這個(gè)值的一個(gè)副本來執(zhí)行
func (u user) notify() 

//bill是user類型的變量名极颓,方法notify會接收到bill的值的一個(gè)副本
bill.notify()
  1. 指針變量 調(diào)用 值接收者聲明的方法
//指針變量lisa 調(diào)用 值接收者聲明的方法notify()
lisa.notify()

//go語言在背后實(shí)際執(zhí)行的動作,但有一點(diǎn)始終沒變群嗤,
//就是notify調(diào)用的一直是值的副本
//這里也是調(diào)用的指針指向的值的副本
(*lisa).notify()
  1. 指針接收者申明的方法與調(diào)用
//該方法使用指針接收者聲明
//接收者的類型是指向user類型值的指針菠隆,而不是user類型的值
func (u *user) changeEmail(email string)

//當(dāng)調(diào)用使用指針接收者聲明的方法時(shí),這個(gè)方法會共享調(diào)用方法時(shí)接收者所指向的值
lisa.changeEmail("lisaNew@email.com")
  1. 普通變量 調(diào)用 指針接收者聲明的方法
//普通變量bill 調(diào)用 指針接收者聲明的方法changeEmail
bill.changeEmail("billNew@email.com")

//go也做了調(diào)整狂秘,實(shí)際動作如下
(&bill).changeEmail("billNew@email.com")

總結(jié)兩點(diǎn):

  1. 值接收者使用值的副本來調(diào)用方法骇径,而指針接收者使用實(shí)際值來調(diào)用方法。
  2. 普通變量和指針變量 都能調(diào)用不同聲明類型的方法者春,實(shí)際是否影響原值破衔,需判斷方法的接收者是指針接收者還是值接收者
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钱烟,一起剝皮案震驚了整個(gè)濱河市晰筛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拴袭,老刑警劉巖传惠,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異稻扬,居然都是意外死亡卦方,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門泰佳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盼砍,“玉大人,你說我怎么就攤上這事逝她〗阶” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵黔宛,是天一觀的道長近刘。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么觉渴? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任介劫,我火速辦了婚禮,結(jié)果婚禮上案淋,老公的妹妹穿的比我還像新娘座韵。我一直安慰自己,他們只是感情好踢京,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布誉碴。 她就那樣靜靜地躺著,像睡著了一般瓣距。 火紅的嫁衣襯著肌膚如雪黔帕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天蹈丸,我揣著相機(jī)與錄音成黄,去河邊找鬼。 笑死白华,一個(gè)胖子當(dāng)著我的面吹牛慨默,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弧腥,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼厦取,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了管搪?” 一聲冷哼從身側(cè)響起虾攻,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎更鲁,沒想到半個(gè)月后霎箍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澡为,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年漂坏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媒至。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡顶别,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拒啰,到底是詐尸還是另有隱情驯绎,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布谋旦,位于F島的核電站剩失,受9級特大地震影響屈尼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拴孤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一脾歧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乞巧,春花似錦涨椒、人聲如沸摊鸡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽免猾。三九已至是辕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猎提,已是汗流浹背获三。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锨苏,地道東北人疙教。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像伞租,于是被迫代替她去往敵國和親贞谓。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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