2013-12-10 7 views
7

Quando apro una connessione socket, inserisco immediatamente la logica socket.Close() in una funzione posticipata dopo l'apertura del socket. Tuttavia, cosa succede se il socket.Close() causerebbe un altro panico? Devo annidare sempre un altro rinvio/recupero all'interno del differimento esterno per evitare che il mio programma si arresti? Qualcosa di simile a questo: http://play.golang.org/p/GnEMQS-0jjConnessione sicura in Golang

Grazie, ELGS

+2

socket.Close() non può causare un errore irreversibile IIRC. – fuz

+2

Non sono perfettamente sicuro: Chiudi (ad esempio un net.TCPConn) potrebbe causare un errore, ma penso che non ci sia il panico. E se si lascia prendere dal panico, ad es. a causa della corruzione dell'hardware o della memoria insufficiente, l'app viene comunque scaricata. A seconda del caso, potresti voler gestire l'errore restituito, ma gestire un panico in Close sembra un po 'paranoico. – Volker

+0

@FUZxxl quando provo a chiudere un socket client che viene rifiutato di connettersi dal server, va in panico. C'è un modo per dire se un socket è sicuro per chiudere senza farsi prendere dal panico. O devo nidificare un altro livello di differimento solo per la logica di chiusura del socket. –

risposta

7

Generalmente non è necessario preoccuparsi molto di panico. Solitamente rappresentano due classi di errori: errori dello sviluppatore (riferimenti nil, array fuori limite) e errori a livello di sistema di cui probabilmente non si può fare molto (come l'esaurimento della memoria).

Come altri hanno affermato, non si lascia prendere dal panico, piuttosto restituisce un errore. Se lo fai:

defer socket.Close() 

L'errore è scartato e non è necessario fare altro.

Ma supponiamo di voler riprendersi dal panico. Se sei gestore di recupero è differito in primo luogo allora non c'è bisogno di fare altro:

func main() { 
    defer func() { 
    if err := recover(); err != nil { 
     fmt.Println(err) 
    } 
    }() 
    defer panic("this will be recovered") 
} 

funzioni differite vengono eseguiti in ordine inverso: http://golang.org/ref/spec#Defer_statements

funzioni differite vengono eseguite immediatamente prima del circostante funzione restituisce, nell'ordine inverso sono stati rinviati.