2013-10-12 5 views
59

जाओ में, यदि आप एक नए प्रकार उदा .:मैं उपनाम कार्यों को टाइप क्यों कर सकता हूं और बिना कास्टिंग किए उनका उपयोग कर सकता हूं?

type MyInt int 

परिभाषित फिर आप विपरीत पारित कर सकते हैं नहीं एक समारोह के लिए एक MyInt किसी पूर्णांक की उम्मीद कर, या इसके:

func test(i MyInt) { 
    //do something with i 
} 

func main() { 
    anInt := 0 
    test(anInt) //doesn't work, int is not of type MyInt 
} 

ठीक। लेकिन फिर यह क्यों है कि यह कार्यों पर लागू नहीं होता है? उदा .:

type MyFunc func(i int) 
func (m MyFunc) Run(i int) { 
    m(i) 
} 

func run(f MyFunc, i int) { 
    f.Run(i) 
} 

func main() { 
    var newfunc func(int) //explicit declaration 
    newfunc = func(i int) { 
     fmt.Println(i) 
    } 
    run(newfunc, 10) //works just fine, even though types seem to differ 
} 
अब

, मैं शिकायत नहीं कर रहा हूँ, क्योंकि यह बचाता है मुझे होने स्पष्ट MyFunc टाइप करने के लिए, जैसा कि मैंने पहले उदाहरण में क्या करना होगा newfunc कास्ट करने के लिए; यह सिर्फ असंगत लगता है। मुझे यकीन है कि इसके लिए एक अच्छा कारण है; क्या कोई मुझे प्रबुद्ध कर सकता है?

कारण मैं पूछ मुख्य रूप से, क्योंकि मैं अपनी नहीं बल्कि लंबे प्रकार समारोह से कुछ इस तरह से कम करने के लिए चाहते हैं, लेकिन मुझे यकीन है कि यह उम्मीद है बनाना चाहते और ऐसा करने के लिए :)

+3

** जाओ में, वहाँ एक 'प्रकार alias' जैसी कोई चीज नहीं है। **' type' कीवर्ड नए प्रकार नामित परिचय देता है। वे उपनाम नहीं हैं। (यह विभिन्न अन्य भाषाओं की तुलना में गो की महत्वपूर्ण ताकत है) –

+0

@ रिक -777 टाइप उपनाम जैसी चीज है, उदाहरण के लिए 'byte' 'uint8' के लिए उपनाम है और' rune' 'int32' के लिए उपनाम है, लेकिन यह सच है कि 'टाइप' कीवर्ड उपनाम नहीं बल्कि नए प्रकार बना देता है। – icza

+0

हां, यह इंगित करने के लिए धन्यवाद - दो विशेष मामले हैं: बाइट और रने। ये * उपनाम हैं, लेकिन किसी भी नए उपनाम बनाना संभव नहीं है। https://golang.org/ref/spec#Numeric_types –

उत्तर

107

बाहर कर देता है स्वीकार्य इस,

http://golang.org/ref/spec#Type_identity

प्रासंगिक अंतर यह है कि मैं के के नाम पर रखा गया गया था कि अनजान था और: एक गलतफहमी है कि मैं के बारे में कैसे जाएं प्रकार के साथ पेश किया था, जो कल्पना की प्रासंगिकता का पढ़कर हल किया जा सकता है अज्ञात प्रकार।

नाम प्रकार नाम, int, int64, float, string, bool जैसे नाम हैं। इसके अतिरिक्त, 'टाइप' का उपयोग करके आप जो भी प्रकार बनाते हैं वह एक नामित प्रकार है।

अनाम प्रकार [] स्ट्रिंग, मानचित्र [स्ट्रिंग] स्ट्रिंग, [4] int जैसे हैं। उनके पास कोई नाम नहीं है, बस यह वर्णन है कि उन्हें कैसे संरचित किया जाना चाहिए।

यदि आप दो नामित प्रकारों की तुलना करते हैं, तो नामों को एक दूसरे के बदले में मिलान करना चाहिए। यदि आप नामित और एक अनाम नाम की तुलना करते हैं, तो जब तक अंतर्निहित प्रतिनिधित्व से मेल खाता है, तो आप जाने के लिए अच्छे हैं!

उदा। दिए गए निम्नलिखित प्रकार:

type MyInt int 
type MyMap map[int]int 
type MySlice []int 
type MyFunc func(int) 

निम्नलिखित अमान्य है:

var i int = 2 
var i2 MyInt = 4 
i = i2 //both named (int and MyInt) and names don't match, so invalid 

निम्नलिखित ठीक है:

is := make([]int) 
m := make(map[int]int) 
f := func(i int){} 

//OK: comparing named and unnamed type, and underlying representation 
//is the same: 
func doSlice(input MySlice){...} 
doSlice(is) 

func doMap(input MyMap){...} 
doMap(m) 

func doFunc(input MyFunc){...} 
doFunc(f) 

मैं थोड़ा निराश मुझे लगता है कि जल्दी ही पता नहीं था, इसलिए मुझे आशा है कि किसी और के लिए लार्क प्रकार को थोड़ा सा स्पष्ट करें! और इसका मतलब है कि पहले विचार पर मुझे बहुत कम कास्टिंग :)

+0

यह लिंक भी मदद करता है: http://golang.org/ref/spec#Type_declarations –

10

दोनों प्रश्न और उत्तर बहुत प्रबुद्ध हैं। हालांकि, मैं एक भेद उठाना चाहता हूं जो लाइट्नस के उत्तर में स्पष्ट नहीं है।

  • नाम टाइप से बेनाम प्रकार अलग है।

  • की नाम टाइप चर का बेनाम प्रकार, ठीक इसके विपरीत चर करने के लिए आबंटित है।

  • विभिन्न के परिवर्तनीय नाम एक-दूसरे को असाइन करने योग्य नहीं है।

http://play.golang.org/p/uaYHEnofT9

import (
    "fmt" 
    "reflect" 
) 

type T1 []string 
type T2 []string 

func main() { 
    foo0 := []string{} 
    foo1 := T1{} 
    foo2 := T2{} 
    fmt.Println(reflect.TypeOf(foo0)) 
    fmt.Println(reflect.TypeOf(foo1)) 
    fmt.Println(reflect.TypeOf(foo2)) 

    // Output: 
    // []string 
    // main.T1 
    // main.T2 

    // foo0 can be assigned to foo1, vice versa 
    foo1 = foo0 
    foo0 = foo1 

    // foo2 cannot be assigned to foo1 
    // prog.go:28: cannot use foo2 (type T2) as type T1 in assignment 
    // foo1 = foo2 
} 
संबंधित मुद्दे

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