go是函數式程式設計語言嗎?

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

[2012-05-19 翻譯自這裡, 對原文有所擴充, 也有所刪減. 著作權屬於原作者, 轉載必須保留此聲明.]


go是函數式程式設計語言嗎?不是, 當然不是.
那麼, go提供函數嗎?是的, 當然, 大多數程式設計語言都提供函數, go也不例外. 
func SayHello() {    fmt.Println("Hello")}
go使用關鍵字func定義函數, 並在函數體中編寫函數邏輯. 
go函數可以接受參數嗎?額, 這個問題... 哦, 我懂了, 也許是我的SayHello函數給大家造成了錯覺, 我會改造My Code:
func SayHelloToSomeone(name string) {    fmt.Println("Hello " + name + ".")} 
函數SayHelloToSomeone接受一個string類型的參數name.
go函數是否可以有傳回值?是的, 是的, 是的! 就像數學意義上的函數一樣, go函數可以返回給調用者一些東西. 為了示範這一點, 我將重新編寫一個函數:
func GetGreeting (name string) string {   greeting := "Hello " + name + "."   return greeting}// testgreeting := GetGreeting("Bob")fmt.Println(greeting) //outputs "Hello Bob." 
當然這沒有什麼, 其他語言也可以做到. 但是, 準備好接受驚喜了嗎? go函數的傳回值與其他類C語言有些不同, 比如, 你可以為傳回值指定名稱. 這帶來至少2個好處:1. 不需要在函數體中為傳回值定義變數.2. 無需在return語句後加上傳回值. go會自動將傳回值加上.
func GetGreeting (name string) (greeting string) {   greeting = "Hello " + name + "."   return} 
GetGreeting函數為其傳回值指定了名稱: greeting. 在函數體中就可以直接使用greeting變數了, greeting其實就相當於函數中定義的一個局部變數. 而且如你所見, GetGreeting函數的return語句後面沒有加上傳回值, 因為go會自動將greeting變數的值返回給調用者.
go函數可以返回多個值嗎?這, 這, 你是異想天開嗎? 不過強大的go函數能夠做到這一點, 哈哈. 要知道可以有多個傳回值的函數可以避免很多醜陋的代碼, 下面是樣本:
type Stack struct {    pos  int    data [10]int}func (s *Stack) Pop() (value int, ok bool) {    if s.pos > 0 {        s.pos--        ok = true        value = s.data[s.pos]        return    }    ok = false    return} 
代碼中首先定義了Stack類型, 並提供了Pop函數. Pop函數返回2個值: value和ok, 分別代表pop的值和pop操作是否成功.
go函數可以接受一個函數作為參數嗎?嗯, 我想你終於開始集中注意力了. 如果你是一個醫生, 你是否會對每次都需要向你的病人SayHello感到厭煩? 沒關係, go可以協助你. 首先需要定義新的資料結構:
type TormentList struct {    patients []string}// 將[]string(string數組)封裝成TormentList類型的指標func NewTormentList(people []string) *TormentList {   return &TormentList{people}}
接下來, 讓我們悄悄給TormentList類型增加Map方法:
func (g *TormentList) Map(f func(string)) {// 遍曆g.patients, 為其每個value調用f方法for _, val := range(g.patients) {f(val)}} 
Map方法接受f函數作為其輸入參數, f函數接受一個string類型的值. 遍曆TormentList的病人, 並為每個病人調用f函數.現在已經做好了一切準備, 剩下的就是測試了:
patients := []string{"Anand", "David", "Ivan", "JoJo", "Jin", "Mon", "Peter", "Sachin"}gl := NewTormentList(patients)// 還記得上面定義的SayHelloToSomeone函數吧?gl.Map(SayHelloToSomeone)/*outputs the following:Hello Anand.Hello David.Hello Ivan.Hello JoJo.Hello Jin.Hello Mon.Hello Peter.Hello Sachin.*/
  go函數的傳回值可以是函數嗎?讓我們先考慮一個現實問題: 假如你擁有一份吃過壽司的人的清單, 你是否能夠根據人名確定他是否在清單上? 這是個很簡單的問題, 你只需遍曆清單. 嗯, 如果你go的功底很弱, 不知道怎麼遍曆清單那怎麼辦? 沒關係, 我會給你提供一個刷選器:
func Screen(patients []string) func(string) bool {    // 定義匿名函數並返回   return func(name string) bool {       for _, soul := range patients {           if soul == name {               return true           }       }       return false   }} 
Screen方法會將刷選的函數返回給調用方, 這樣你就可以不用懂怎麼去遍曆清單了, 你只需調用我返回給你的函數就可以:
// 吃過壽司的人的清單those_who_bought_sushi := []string{"Anand", "JoJo", "Jin", "Mon", "Peter", "Sachin"}// 得到刷選器函數bought_sushi := Screen(those_who_bought_sushi)// 調用刷選器函數就可以知道某人是否在清單上fmt.Println(bought_sushi("Anand")) // truefmt.Println(bought_sushi("Alex")) // false
 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.