Home >Backend Development >Golang >How to Work with Different Structs with Common Members in Go Using Generics?

How to Work with Different Structs with Common Members in Go Using Generics?

Susan Sarandon
Susan SarandonOriginal
2024-10-26 15:29:30798browse

How to Work with Different Structs with Common Members in Go Using Generics?

Working with Different Structs with Common Members Using Generics

In Go, you may encounter scenarios where you want to create generic functions that operate on different structs that share common members. However, directly accessing such common fields across union type constraints is not yet supported in Go 1.18.

Challenge:

Consider two message structs, Message and MulticastMessage, each containing fields of the same type, such as Android. You want to define a generic function to add these fields to both structs. However, using a type parameter constrained to an interface containing both structs does not allow direct access to their common fields.

Solution:

Solution 1: Type Switch

If there are only a few structs involved, a type switch can be employed:

<code class="go">func highPriority[T firebaseMessage](message T) T {
    switch m := any(message).(type) {
    case *messaging.Message:
        setConfig(m.Android)
    case *messaging.MulticastMessage:
        setConfig(m.Android)
    }
    return message
}</code>

Solution 2: Wrapper with Method

For a large number of structs, consider wrapping each struct with a method that implements the common functionality:

<code class="go">type wrappedMessage interface {
    *MessageWrapper | *MultiCastMessageWrapper
    SetConfig(c foo.Config)
}

func highPriority[T wrappedMessage](message T) T {
    message.SetConfig(messaging.Android{"some-value"})
    return message
}</code>

Solution 3: Reflection

If you have many structs, reflection may be a better option, though it requires addressable structs and fields:

<code class="go">func highPriority[T firebaseMessage](message T) T {
    cfg := &messaging.Android{}
    reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
    return message
}</code>

Notes and Alternatives:

  • If the common members are methods, you may need to implement the methods explicitly for each constraint type.
  • Another approach is to use custom interfaces for the common members. However, this requires modifying the original structs, which may not be feasible in all cases.

The above is the detailed content of How to Work with Different Structs with Common Members in Go Using Generics?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn