不确定如何覆盖回调以调整未导出的字段

What I'd like to do is overwrite some boolean values on a given object, such as:

func main() {
    manager := dshardmanager.New("Bot " + token)
    manager.bareSession.State.TrackRoles = false;
    manager.bareSession.State.TrackPresences = false;

    // more stuff happens down here
}

However bareSession is an unexported field, so I need to do this differently from what I'm gathering. I've come across some approaches using reflection but I'd like to learn the best practices approach to doing this.

In my specific case, it looks like the library I'm using offers a method to accomplish this. I've been tinkering with how to overwrite/define such a method but can't seem to figure out how to go about this.

What's the ideal approach to defining this SessionFunc() to customize the session the way I'm trying to?

I don't know the context of that library, so I'm not sure if what I'll write here makes sense for you :) But by looking at the API, SessionFunc is a func(token string) (*discordgo.Session, error), i.e., a function which receives a string and returns a Session and an error. So you can make something like this to override it:

func main() {
    manager := dshardmanager.New("Bot " + token)
    manager.SessionFunc = func(token string) (*discordgo.Session, error) {
        // use "token"

        // if invalid:
        if token == "" {
            // return an error
            return nil, fmt.Errorf("invalid token")
        }

        // otherwise, return a valid session
        return &discordgo.Session{}
    }

    // more stuff happens down here
}

The code is obviously very generic, but the main idea is that you need to define that function with that exact header, and implement it. I don't know how you can, for example, evaluate the token parameter or create a discordgo.Session. Or how you can configure the TrackRoles or TrackPresences values by using SessionFunc. That's very specific for that library only, but I guess it makes more sense to you than to me :)

You could also define a regular function elsewhere with that exact header:

func createNewSession(token string) (*discordgo.Session, error) {
    // use "token"

    // if invalid:
    if token == "" {
        // return an error
        return nil, fmt.Errorf("invalid token")
    }

    // otherwise, return a valid session
    return &discordgo.Session{}
}

And set it with:

func main() {
    manager := dshardmanager.New("Bot " + token)
    manager.SessionFunc = createNewSession

    // more stuff happens down here
}

Both approaches work the same way.

Reflection is [almost] never the recommended way to do those things, if the library creators made those properties private, they shouldn't be changed/accessed from outside.

This will not allow you to change bareSession. But if you need to derive a new *discordgo.Session with custom parameters you can do something similar to as follows.

func MySessionFunc(m *dshardmanager.Manager) dshardmanager.SessionFunc {
    return func(token string) (*discordgo.Session, error) {
        //Call default Session allocator
        s, err := m.StdSessionFunc(token)
        if err != nil {
            return nil, err
        }
        //Then, change its exported fields
        s.State.TrackRoles = false
        s.TrackPresences = false
        return s, nil
    }
}

func main() {
    manager := dshardmanager.New("Bot " + token)
    manager.SessionFunc = MySessionFunc(manager)
}