我想做的是在给定对象上覆盖一些布尔值,例如:

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

    // more stuff happens down here
}

但是bareSession是未导出的字段,因此我需要做的与我收集的有所不同。我遇到了一些使用反射的方法,但是我想学习最佳实践方法。

在我的特定情况下,它看起来像我正在使用的库提供了一种完成此操作的方法。我一直在修补如何使用overwrite/define这样的方法,但似乎无法弄清楚该如何进行。

定义这个SessionFunc()来以我尝试的方式自定义会话的理想方法是什么?

分析解答

我不知道该库的上下文,所以我不确定在这里写的内容是否对您有意义:)但是通过查看API,SessionFuncfunc(token string) (*discordgo.Session, error),即接收string的函数并返回Sessionerror。因此,您可以进行如下操作来覆盖它:

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
}

该代码显然是非常通用的,但是主要思想是您需要使用该确切的header定义该函数并实现它。例如,我不知道如何评估令牌参数或创建discordgo.Session。或如何使用SessionFunc配置TrackRolesTrackPresences值。这仅是针对该库的,但是我想对您来说比对我来说更有意义:)

您还可以在其他地方使用该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{}
}

并设置为:

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

    // more stuff happens down here
}

两种方法的工作方式相同。

几乎从来都不建议使用反射来做这些事情,如果库创建者将这些属性设为私有,那么它们不应从外部成为changed/accessed。