আমি কেন একটি * ইন্টারফেসের জন্য * স্ট্রাক্ট বরাদ্দ করতে পারি না?


142

আমি কেবল গো ট্যুর দিয়ে কাজ করছি , এবং আমি পয়েন্টার এবং ইন্টারফেস সম্পর্কে বিভ্রান্ত। কেন এই গো কোডটি সংকলন করে না?

package main

type Interface interface {}

type Struct struct {}

func main() {
    var ps *Struct
    var pi *Interface
    pi = ps

    _, _ = pi, ps
}

অর্থাত্ যদি Structএকটি হয় তবে Interfaceকেন একটি হবে না*Struct একটি হতে *Interface?

আমার কাছে পাওয়া ত্রুটি বার্তাটি হ'ল:

prog.go:10: cannot use ps (type *Struct) as type *Interface in assignment:
        *Interface is pointer to interface, not interface

1
আরও দেখুন stackoverflow.com/q/20874798/260805
Ztyx

দেখে মনে হচ্ছে ইন্টারফেসগুলি অন্তর্নিহিত পয়েন্টারগুলির মতো আচরণ করতে পারে ...
ভিক্টর

আমি কি আপনার খেলার func main() { var ps *Struct = new(Struct) var pi *Interface var i Interface i = ps pi = &i fmt.Printf("%v, %v, %v\n", *ps, pi, &i) i = *ps fmt.Printf("%v, %v, %v\n", *ps, pi, i) _, _, _ = i, pi, ps }মাঠটিকে সমৃদ্ধ করার এবং নিজের সিদ্ধান্তে নেওয়ার পরামর্শ দিতে পারি
ভিক্টর

উত্তর:


183

যখন আপনার কোনও ইন্টারফেস প্রয়োগকারী স্ট্রাক্ট থাকে তখন সেই স্ট্রাক্টের একটি পয়েন্টার স্বয়ংক্রিয়ভাবে সেই ইন্টারফেসটি প্রয়োগ করে। এ কারণেই আপনার কোনও *SomeInterfaceক্রিয়াকলাপের প্রোটোটাইপ নেই, কারণ এতে কোনও যোগ হবে না SomeInterfaceএবং আপনার এই ধরণের পরিবর্তনশীল ঘোষণার প্রয়োজন নেই ( এই সম্পর্কিত প্রশ্নটি দেখুন )।

একটি ইন্টারফেসের মানটি কংক্রিট কাঠামোর মান নয় (এটির আকার পরিবর্তনশীল হতে পারে, এটি সম্ভব হবে না) তবে এটি একধরণের পয়েন্টার (কাঠামোর জন্য আরও নির্দিষ্টভাবে নির্দেশক এবং প্রকারের জন্য একটি পয়েন্টার হতে হবে) )। রাশ কক্স ঠিক এখানে বর্ণনা করেছেন :

ইন্টারফেসের মানগুলি দ্বি-শব্দের জোড় হিসাবে প্রতিনিধিত্ব করা হয় যা ইন্টারফেসে সঞ্চিত প্রকারের সম্পর্কিত তথ্য এবং সম্পর্কিত ডেটাতে একটি পয়েন্টার দেয়।

এখানে চিত্র বর্ণনা লিখুন

এই কারণেই Interface, এবং *Interfaceস্ট্রাক্ট বাস্তবায়নের কোনও পয়েন্টার ধরে রাখা সঠিক ধরণ নয় Interface

সুতরাং আপনি অবশ্যই ব্যবহার করা উচিত

var pi Interface

8
ঠিক আছে, আমি মনে করি এটি আমার কাছে বোধগম্য। আমি কেবল ভাবছি কেন (সেই ক্ষেত্রে), এটি কেবল একটি সঙ্কলন সময় ত্রুটি বলে নাvar pi *Interface
সাইমন নিক্কারসন

1
আমি আরও বিশদ এটি ব্যাখ্যা করতে গিয়েছিলাম। সম্পাদনা দেখুন। আমি রাশ কক্সের নিবন্ধটি পড়ার পরামর্শ দিচ্ছি যার সাথে আমি লিঙ্ক করেছি।
Denys Seguret

1
এটি আমাকে এমনভাবে পয়েন্টারগুলি বোঝাতে সহায়তা করেছিল যে আমি কখনই ছিলাম না সি বা সি ++ সক্ষম করতে ... এই মার্জিত এবং সাধারণ ব্যাখ্যাটির জন্য আপনাকে অনেক ধন্যবাদ :-)
mindplay.dk

2
ঠিক আছে, আমি এখনও পাই না কেন *SomeInterfaceকেবল একটি সংকলন ত্রুটি হয় না?
sazary

2
আপনি এখানে পুরোপুরি সঠিক নন। কোনও ইন্টারফেস ভেরিয়েবল ঘোষণার সময় বা কোনও ফাংশন ঘোষণার অংশ হিসাবে কোনও ইন্টারফেস টাইপ ফিরিয়ে দেওয়ার সময় আপনার কখনই * সামিয়ার ইন্টারফেস থাকে না । তবে আপনার কোনও ফাংশনের প্যারামিটারের মধ্যে * সামিআন্টারফেস থাকতে পারে
arauter

7

আপনি সম্ভবত যা বোঝাতে চেয়েছিলেন এটি সম্ভবত:

package main

type Interface interface{}

type Struct struct{}

func main() {
        var ps *Struct
        var pi *Interface
        pi = new(Interface)
        *pi = ps

        _, _ = pi, ps
}

সংকলন ঠিক আছে। এখানেও দেখুন ।


এটি গ্রহণ করা উচিত, অন্যটি সত্যই প্রশ্নের উত্তর দেয় না।
ডাঃকি


0

আমি interface{}কেবল eventsI interface{}আর্গুমেন্ট হিসাবে গ্রাস করার সময় নিম্নলিখিত পদ্ধতি ব্যবহার করছি , আপনি এখনও নীচে দেখতে পারেন এমন কোনও স্ট্রাক্ট পয়েন্টার পাঠাতে সক্ষম।

func Wait(seconds float64) *WaitEvent {
    return WaitEventCreate(seconds)
}

main.go

var introScene = []interface{}{
        storyboard.Wait(5),
        storyboard.Wait(2),
    }

    var storyboardI = storyboard.Create(stack, introScene)
    stack.Push(&storyboardI)

এখন storyboard.goফাইল তৈরি করুন ফাংশন ভিতরে

type Storyboard struct {
    Stack  *gui.StateStack
    Events []interface{} //always keep as last args
}

func Create(stack *gui.StateStack, eventsI interface{}) Storyboard {
    sb := Storyboard{
        Stack: stack,
    }

    if eventsI != nil {
        events := reflect.ValueOf(eventsI)
        if events.Len() > 0 {
            sb.Events = make([]interface{}, events.Len())
            for i := 0; i < events.Len(); i++ {
                sb.Events[i] = events.Index(i).Interface()
            }
        }
    }

    return sb
}

আপনি উপরে দেখতে পারেন স্টোরিবোর্ড.গো ঠিকই গ্রাস করছে Events []interface{} তবে প্রকৃতপক্ষে ইম প্রেরণ করা একটি স্ট্রাক্ট পয়েন্টার এবং এটি দুর্দান্ত কাজ করে।

এখানে আরও একটি উদাহরণ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.