मैं अन्य कार्यों को क्यों टाइप कर सकता हूं और उन्हें बिना कास्टिंग के उपयोग कर सकता हूं?


97

में, यदि आप एक नए प्रकार को परिभाषित करते हैं जैसे:

type MyInt int

फिर आप MyIntएक int, या इसके विपरीत की अपेक्षा कर रहे फ़ंक्शन को पास नहीं कर सकते :

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
}

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

मेरे द्वारा पूछे जाने का मुख्य कारण यह है कि मैं इस तरह से अपने कुछ लंबे फ़ंक्शन प्रकारों को छोटा करना चाहूंगा, लेकिन मैं यह सुनिश्चित करना चाहता हूं कि ऐसा करने की उम्मीद है और स्वीकार्य है :)


typeबल्कि स्काला की तुलना में गो में अधिक उपयोगी है। स्काला में केवल उपनाम, उपनाम हैं।
रिक -777

4
अब वास्तव में टाइप करें उपनाम github.com/golang/go/issues/18130
Hut8

क्या कोई दूसरा कोड स्निपेट समझा सकता है? मैं वास्तव में उन कार्यों की घोषणा नहीं कर सकता
DevX

जवाबों:


148

पता चला, यह एक गलतफहमी है कि मेरे पास इस बारे में था कि गो किस प्रकार से निपटा जाता है, जिसे कल्पना के प्रासंगिक हिस्से को पढ़कर हल किया जा सकता है:

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

जिस प्रासंगिक भेद से मैं अनभिज्ञ था, वह नाम और अनाम प्रकार का था।

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

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

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

निम्न प्रकार दिए गए:

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)

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


1
आप उपयोग भी कर सकते हैं is := make(MySlice, 0); m := make(MyMap), जो कुछ संदर्भों में अधिक पठनीय है।
R2B2

13

सवाल और जवाब दोनों ही काफी ज्ञानवर्धक हैं। हालाँकि, मैं एक अंतर लाना चाहूँगा जो कि लिटनस के उत्तर में स्पष्ट नहीं है।

  • नामांकित प्रकार से अलग है बेनाम प्रकार

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

  • विभिन्न नाम प्रकार के परिवर्तनीय एक दूसरे के लिए उपलब्ध नहीं है।

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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.