2012-07-17 10 views
13

मुझे आश्चर्य है कि गोलांग में एक प्रकार के स्विच स्टेटमेंट में गिरावट की अनुमति क्यों नहीं है।एक प्रकार के स्विच में गिरावट की अनुमति क्यों नहीं है?

specification के मुताबिक: "गिरावट" कथन को एक प्रकार के स्विच में अनुमति नहीं है। ", जो इस बारे में ज्यादा नहीं बताता है कि इसकी अनुमति क्यों नहीं है।

संलग्न कोड एक संभावित परिदृश्य अनुकरण करना है, एक प्रकार स्विच स्टेटमेंट में गिरावट उपयोगी हो सकती है।

नोटिस! यह कोड काम नहीं करता है, यह त्रुटि उत्पन्न करेगा: "प्रकार स्विच में गिरावट नहीं हो सकती"। मैं बस सोच रहा हूं कि एक प्रकार के स्विच में गिरावट के वक्तव्य की अनुमति न देने के लिए क्या संभव कारण हो सकते हैं।

//A type switch question 
package main 

import "fmt" 

//Why isn't fallthrough in type switch allowed? 
func main() { 
    //Empty interface 
    var x interface{} 

    x = //A int, float64, bool or string value 

    switch i := x.(type) { 
    case int: 
     fmt.Println(i + 1) 
    case float64: 
     fmt.Println(i + 2.0) 
    case bool: 
     fallthrough 
    case string: 
     fmt.Printf("%v", i) 
    default: 
     fmt.Println("Unknown type. Sorry!") 
    } 
} 

उत्तर

29

आप काम करने के लिए fallthrough की अपेक्षा कैसे करेंगे? इस प्रकार स्विच में, i वैरिएबल में एक प्रकार है जो लागू किए गए विशेष मामले पर निर्भर करता है। तो case bool में i चर bool के रूप में टाइप किया गया है। लेकिन case string में इसे string के रूप में टाइप किया गया है। तो या तो आप i के लिए जादुई रूप से इसके प्रकार को मॉर्फ करने के लिए कह रहे हैं, जो संभव नहीं है, या आप इसे एक नए चर i string द्वारा छायांकित करने के लिए कह रहे हैं, जिसका कोई मूल्य नहीं होगा क्योंकि इसका मान x से आता है जो नहीं है वास्तव में, string


यहाँ एक उदाहरण है कोशिश करते हैं और समस्या को वर्णन करने के:

switch i := x.(type) { 
case int: 
    // i is an int 
    fmt.Printf("%T\n", i); // prints "int" 
case bool: 
    // i is a bool 
    fmt.Printf("%T\n", i); // prints "bool" 
    fallthrough 
case string: 
    fmt.Printf("%T\n", i); 
    // What does that type? It should type "string", but if 
    // the type was bool and we hit the fallthrough, what would it do then? 
} 

ही संभव समाधान fallthrough कारण i एक interface{} के रूप में छोड़ने के लिए बाद में मामला अभिव्यक्ति बनाने के लिए हो सकता है, लेकिन यह है कि हो सकता है एक भ्रमित और बुरी परिभाषा।

तुम सच में इस व्यवहार की जरूरत है आप पहले से ही मौजूदा कार्यक्षमता के साथ ऐसा कर सकते हैं:

switch i := x.(type) { 
case bool, string: 
    if b, ok := i.(bool); ok { 
     // b is a bool 
    } 
    // i is an interface{} that contains either a bool or a string 
} 
+0

@KevinBallard, मेरा बुरा। – Ben

+0

स्पष्टीकरण के लिए धन्यवाद, लेकिन मुझे स्वीकार करना होगा कि मैं वास्तव में समझ नहीं पा रहा हूं कि fmt.Printf ("% T \ n", i) फिर से "बूल" प्रिंट नहीं करेगा। चूंकि नियमित गिरावट में केस स्टेटमेंट को नजरअंदाज कर दिया जाता है और अभिव्यक्ति प्रकार अनजान होती है। ऐसा शायद इसलिए है क्योंकि मैं इसे नियमित स्विच स्टेटमेंट से बहुत अधिक बता रहा हूं कि मुझे यह पता लगाने में कठिन समय है। – Karlek

+2

@Mandarin: कोड 'i'' स्ट्रिंग' संकलित करता है यदि संकलित नहीं हो सकता है 'i' 'bool' है। आप कोड लिख नहीं सकते हैं जो एक वैरिएबल का इलाज करता है जैसे कि इसमें दो अलग-अलग प्रकार हैं। तो 'केस बूल' में किस प्रकार का होगा? यह निश्चित रूप से 'बूल' नहीं हो सकता है, और यदि यह 'स्ट्रिंग' है तो आपको अनिवार्य रूप से उस मूल्य को त्यागना होगा जो 'केस बूल' में था, और उसके कोड के बिना आपका कोड बेकार है। –

संबंधित मुद्दे