有没有一种方法可以将结构体转换为发送到通道的形式?

huangapple go评论77阅读模式
英文:

Is there a way to cast Structs for sending over a channel

问题

在GOLANG中,是否有一种简单的方法可以将结构体转换为多态行为以跨通道传递?我试图通过一个通道发送不同版本的结构体,例如我将拥有不同类型的事件,比如一个LoginEvent。每个事件的结构体中将有不同数量的数据。

package main

import "fmt"


type Event struct {
    EvtType   EvtType
    Username  string
    Data      string
}


type LoginEvent struct {
    Event
    CallBackChannel chan *Event
}


type EvtType int

const (
    Login EvtType = iota + 1
    Logout
    ChatMessage
    Presense
    BuddyList
)


func main() {
    fakeOutputChan := make(chan<- *Event)

    ourSrvChannel := make(chan *Event)
    lg := (LoginEvent{Event{Login, "", ""}, ourSrvChannel})
    fakeOutputChan <- (*Event)(&lg)

    fmt.Println("Hello, playground")
}
英文:

In GOLANG is there an easy to way to cast structs for polymorphic behavior across channels? I'm trying to send different versions of a struct across one channel, so for example I'm going to have different types of Events, like a LoginEvent. Each one will have different amounts of data in the struct.

package main

import &quot;fmt&quot;


type Event struct {
	EvtType EvtType
	Username string
	Data string
}


type LoginEvent struct {
	Event
	CallBackChannel  chan *Event
}


type EvtType int

const (
    Login EvtType = iota+1
    Logout
    ChatMessage
    Presense
    BuddyList
)


func main() {
	fakeOutputChan := make(chan&lt;- *Event)

        ourSrvChannel := make(chan *Event)
        lg := (LoginEvent{Event{Login,&quot;&quot;,&quot;&quot;} ,ourSrvChannel})
	fakeOutputChan &lt;- (*Event)(&amp;lg)

	fmt.Println(&quot;Hello, playground&quot;)
}

答案1

得分: 27

The idiomatic way to do is, is to use interfaces and then do a type assertion on the receiving end. Your Event struct should ideally be an interface.

type Event interface {
	// Methods defining data all events share.
}

type UserEvent struct {
	Name string
}

// Define methods on *UserEvent to have it qualify as Event interface.

type LoginEvent struct {
	...
}

// Define methods on *LoginEvent to have it qualify as Event interface.

Then you can define your channel to accept anything that qualifies as the Event interface.

ch := make(chan Event)

The receiving end will receive the Event objects and can do a type assertion to see what
concrete type underlies it:

select {
case evt := &lt;- ch:
	if evt == nil {
		return
	}
	
	switch evt.(type) {
	case *LoginEvent:
	
	case *UserEvent:
	
	....
	}
}
英文:

The idiomatic way to do is, is to use interfaces and then do a type assertion on the receiving end. Your Event struct should ideally be an interface.

type Event interface {
	// Methods defining data all events share.
}

type UserEvent struct {
	Name string
}

// Define methods on *UserEvent to have it qualify as Event interface.

type LoginEvent struct {
	...
}

// Define methods on *LoginEvent to have it qualify as Event interface.

Then you can define your channel to accept anything that qualifies as the Event interface.

ch := make(chan Event)

The receiving end will receive the Event objects and can do a type assertion to see what
concrete type underlies it:

select {
case evt := &lt;- ch:
	if evt == nil {
		return
	}
	
	switch evt.(type) {
	case *LoginEvent:
	
	case *UserEvent:
	
	....
	}
}

huangapple
  • 本文由 发表于 2012年11月17日 06:39:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/13425490.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定