2015-09-29 10 views
13

Desidero eseguire un set di codice finché l'utente non desidera esplicitamente uscire dalla funzione. Per esempio: quando un utente esegue il programma, vedrà 2 opzioni:Come replicare mentre si è in viaggio?

  1. Run nuovo
  2. Exit

questo sarà ottenuto utilizzando struttura case interruttore. Qui se l'utente preme 1, verrà eseguita l'insieme delle funzioni associate a 1 e se l'utente preme 2, il programma uscirà. Come devo raggiungere questo scenario in golang? In Java, credo che questo potrebbe essere fatto usando do mentre la struttura, ma non supporta il ciclo while. In seguito è il mio codice che ho provato, ma questo va in un ciclo infinito:

func sample() { 
    var i = 1 
    for i > 0 { 
     fmt.Println("Press 1 to run") 
     fmt.Println("Press 2 to exit") 
     var input string 
     inpt, _ := fmt.Scanln(&input) 
     switch inpt { 
     case 1: 
      fmt.Println("hi") 
     case 2: 
      os.Exit(2) 
     default: 
      fmt.Println("def") 
     } 
    } 
} 

Il programma indipendentemente dell'ingresso, stampa solo "ciao". Qualcuno potrebbe, per favore, correggermi, che cosa sto sbagliando?

Grazie.

+0

Si prega di restituire a questa domanda e cambia la tua risposta accettata. La risposta che hai accettato è ottima per il tuo caso specifico, ma la tua domanda è molto generica, e c'è una risposta che è molto meglio per la domanda generale che hai posto. Questa dovrebbe essere la risposta accettata: https://stackoverflow.com/a/32844744/167958 – Omnifarious

risposta

6

Quando è stata posta questa domanda, questa era una risposta migliore per questo specifico scenario (non sapevo che questo sarebbe stato il risultato n. 1 durante la ricerca di Google "do while loop golang"). Per rispondere a questa domanda in generale, vedere @LinearZoetrope's answer below.

avvolgere la funzione in un ciclo for:

package main 

import (
    "fmt" 
    "os" 
) 

func main() { 
    fmt.Println("Press 1 to run") 
    fmt.Println("Press 2 to exit") 
    for { 
     sample() 
    } 
} 

func sample() { 
    var input int 
    n, err := fmt.Scanln(&input) 
    if n < 1 || err != nil { 
     fmt.Println("invalid input") 
     return 
    } 
    switch input { 
    case 1: 
     fmt.Println("hi") 
    case 2: 
     os.Exit(2) 
    default: 
     fmt.Println("def") 
    } 
} 

Un for ciclo senza eventuali dichiarazioni è equivalente a un ciclo while in altre lingue C-like. Controlla il Effective Go documentation che copre il ciclo for.

+0

questo continua a stampare "ciao". Anche se diamo input da linea di comando come 2, stampa "hi" invece di uscire dal programma. –

+0

Il mio errore. Il caso switch deve essere modificato. – Lander

+1

Quindi l'errore con l'input originale era che veniva utilizzato il valore di ritorno da Scanln. La [documentazione] (https://golang.org/pkg/fmt/#Scanln) afferma che il ritorno è un errore/numero di argomenti analizzati, che non è il modo in cui si desidera utilizzarlo. Questo dovrebbe farti cominciare. – Lander

34

A do..while È possibile emulare più direttamente in Go con un ciclo for utilizzando una variabile di ciclo bool seminata con true.

for ok := true; ok; ok = EXPR { } 

è più o meno direttamente equivalente a

do { } while(EXPR) 

Quindi nel tuo caso:

var input int 
for ok := true; ok; ok = (input != 2) { 
    n, err := fmt.Scanln(&input) 
    if n < 1 || err != nil { 
     fmt.Println("invalid input") 
     break 
    } 

    switch input { 
    case 1: 
     fmt.Println("hi") 
    case 2: 
     // Do nothing (we want to exit the loop) 
     // In a real program this could be cleanup 
    default: 
     fmt.Println("def") 
    } 
} 

Edit: Playground (con un dummied-out Stdin)

Anche se, certamente, in questo caso è probabilmente più chiaro in generale chiamare semplicemente (etichettato) break, return o os.Exit nel ciclo.

+0

Questa risposta dovrebbe essere accettata in quanto è idiomatica e replica esattamente 'do while' mentre la risposta corrente accetta semplicemente la dichiarazione' while' –

0

Forse non è quello che stiamo cercando, ma se si sta cercando di fare qualcosa di simile:

int i = 0; 
while (i < 10) { 
    cout << "incrementing i now" << endl; 
    i++ 
} 
cout << "done" 

dovrete fare qualcosa di simile a Go:

var i = 0 
    fmt.Println(i) 
    for { 
      if i < 10 { 
        fmt.Println("incrementing i now") 
        i++ 
      } else { 
        break 
      } 
    } 
    fmt.Println("done") 
+2

Go ha invece regolari "cicli while": 'per a> b {...} '. Ciò che OP sta chiedendo è un 'do {...} while (a> b);' loop –

6

un ciclo while in Go può essere facile come questo:

package main 

    import `fmt` 

     func main() { 
     for { 
      var number float64 
      fmt.Print(`insert an Integer eq or gr than 10!!!`) 
      fmt.Scanf(`%f`, &number) 
      if number >= 10 { break } 
      fmt.Println(`sorry the number is lower than 10....type again!!!`) 
     } 
+0

Questa è una dichiarazione di ciclo * infinito *, piuttosto che un ciclo while. Un ciclo while avrebbe una condizione. –

+0

@VictorZamanian c'è una condizione: 'se numero> = 10 {pausa}'. A tutti gli effetti, un ciclo infinito con un'interruzione condizionale alla fine equivale a un ciclo 'do..while' che è esattamente ciò che l'OP stava chiedendo. – 3ocene

+0

@ 3ocene Hai ragione. –

3

Conside da utilizzare "per-break" come "mentre do-".

foo.go

package main 

import (
     "fmt" 
) 

func main() { 
     i := 0 
     for { 
       i++ 
       if i > 10 { 
         break 
       } 
       fmt.Printf("%v ", i) 
     } 
     fmt.Println() 
} 

guscio

$ go run foo.go 
1 2 3 4 5 6 7 8 9 10 
+0

È lo stesso di 'for i: = 0; i <10; i ++ {fmt.Printf ("% v", i)} '. Forse hai intenzione di mettere la dichiarazione di stampa all'inizio del ciclo? – 3ocene

4

DO ... mentre in movimento può essere questo:

func main() { 
    var value int 
    for { 
     value++ 
     fmt.Println(value) 
     if value%6 != 0 { 
      break 
     } 
    } 
} 
Problemi correlati