Ich benutze Protobuf für Golang. Protobuf generiert Nachrichtentypen, bei denen der Typzeiger proto.Message()
implementiert. z.B.Cast boxed struct zu boxed pointer - golang
func (*SomeMessage) Message() {}
Die protobuf lib haben Methoden wie Marshal(proto.Message)
Nun zu meiner eigentlichen Frage.
message := SomeMessage {}
SendMessage(&message)
func SendMessage(message interface{}) {
switch msg := message.(type) {
case proto.Message:
//send across the wire or whatever
default:
//non proto message, panic or whatever
}
}
Das obige funktioniert gut. Wenn ich die Nachricht jedoch nicht als Zeiger übergebe, stimmt der Code in SendMessage nicht überein, da die Schnittstelle nur im SomeMessage-Zeiger und nicht im Wert implementiert ist.
Was ich mag würde zu tun ist:
message := SomeMessage {}
SendMessage(message) //pass by value
//there are more stuff going on in my real code, but just trying to show the relevant parts
func SendMessage(message interface{}) {
//match both pointer and value as proto.Message
//and then turn the value into a pointer so that
//other funcs or protobuf can consume it
message = MagicallyTurnBoxedValueIntoBoxedStruct(message)
switch msg := message.(type) {
case proto.Message:
//send across the wire or whatever
default:
//non proto message, panic or whatever
}
}
bevorzugt würde ich beide in der Lage sein mag als Zeiger übergeben und als Wert. Der Grund, warum ich nach Wert zu übergeben will, ist, dass dies als eine schlechte mans Isolation wirken kann, wenn Nachrichten über goroutines/Threads usw. (in Mangel an Unveränderlichkeit) diesen
alle vorbei wahrscheinlich vermieden werden kann, wenn die Protobuf Generator generierte erlaubte Werte, die wie proto.Message()
behandelt werden. Oder wenn es eine bessere Möglichkeit gäbe, unveränderliche Nachrichten zu machen.
Es ist nicht super wichtig, wenn sie möglich, cool, wenn sie nicht, meh :-)
[EDIT]
Wenn ich die reflect.Type der Nachricht und die reflect.Type von der Zeigertyp der Nachricht Ist es irgendwie möglich, eine Instanz des Zeigertyps zu erstellen, der mit "reflect" auf den Wert zeigt?
Das funktioniert, danke! –
@RogerAlsing Ich möchte darauf hinweisen, dass es dabei zwar extrem langsam und überentwickelt ist und in keinem realen Projekt verwendet werden sollte. – OneOfOne
Ja, ich bekomme das, die beste Lösung wäre, wenn ich ein Protokoll erzeugen würde, das unveränderliche Strukturen erzeugt. Aber es war immer noch interessant zu sehen, dass es möglich war. –