2017-07-06 114 views
0

我很抱歉我的英語。 我有兩個關於go語言代碼的問題。這是我的程序。 該程序控制「數據庫」中暱稱的存在。Go(Golang) - 轉到主要和打印主題goto的定義

package main 

import "fmt" 

func rcv(){ 
    if r := recover() ; r != nil { 
    fmt.Println("retry.") 
    main() 
    } 
} 
func main(){ 
defer rcv() 
INSERT: 
    fmt.Println("Insert a nickname: ") 
    var s string 
    fmt.Scanln(&s) 
    switch { 
    case len(s) <= 0 : 
    fmt.Println(fmt.Errorf("error empty")) 
    goto INSERT 
    case s=="mark"||s=="andrea": 
    fmt.Println("Accept, the nickname is",s) 
    default : 
    fmt.Println("ATTENTION, nickname not found") 
    panic("Error.") 
    } 
} 

我的問題是:

  1. 使用恢復功能(RCV()),在它的結束,召回的main()函數運行像另一個線程發送?主體main()函數在執行第二個函數或每當引發恐慌時結束,recover函數創建另一個進程? (例如:如果輸入的暱稱錯誤5次,則會啓動5個主要函數,所以6個主要運行函數?)如果創建多次執行main(),是否有方法來打印線程/進程ID或類似的東西?

  2. 我使用了INSERT標籤和goto構造。我可以在主函數之外使用goto(例如:在rcv()函數的末尾返回到主函數的頂部)? 我可以使用goto語句,而不是調用main()函數在RCV()結束

+0

您是否嘗試過?從規範「標籤的範圍是它聲明的函數的主體,並排除任何嵌套函數的主體」。 – JimB

+0

我已經嘗試在rcv()函數中插入goto INSERT,但是說我沒有聲明標籤。 – mx88

+0

是的,所以沒有回答這個問題?我不明白問題1,你沒有創建任何新的進程或線程,甚至沒有goroutines。雖然我會推薦構造這個表單的另一個函數,就像調用main()一樣,這個函數很少引起混淆,因爲你爲什麼要這麼做。 – JimB

回答

0

1.關於推遲

defer語句執行函數退出作用範圍之前。所以執行defer-func時,堆棧的調用者函數是剩餘的。

func foo() (err error) { 
    defer func() { 
     err = io.EOF 
    }() 
} 

它將與stackoverflow

2.關於轉到崩潰

documentation

A 「轉到」 語句將控制權交給聲明具有相同功能的內對應的標籤。

所以你不能在外面的func標籤。

3.關於問題

我怎麼回main()函數的開始?

package main 

func Main() { 
    // do your main 
} 

func main() { 
    for { 
     Main() 
    } 
} 
+0

正如我所想的那樣,延遲函數是main()函數的一部分,所以main()函數的額外調用不會結束前一個函數。 這個程序做我期望的,但我有這些懷疑。我如何回到main()函數的開頭?我是否應該強迫它停止或創建其他功能並對其進行更好的管理? – mx88

+0

只要讓主要做你的主要部分像上面一樣。並使其循環。 – mattn