Go 不确定如何覆盖回调以调整未报告的字段

Go 不确定如何覆盖回调以调整未报告的字段,go,discord,Go,Discord,我要做的是覆盖给定对象上的一些布尔值,例如: func main() { manager := dshardmanager.New("Bot " + token) manager.bareSession.State.TrackRoles = false; manager.bareSession.State.TrackPresences = false; // more stuff happens down here } 然而,bareSession是一个未报告

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

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

    // more stuff happens down here
}

然而,bareSession是一个未报告的字段,所以我需要以不同于我正在收集的方式来执行此操作。我遇到过一些使用反射的方法,但我想学习使用反射的最佳实践方法

在我的具体案例中,它看起来像。我一直在修补如何覆盖/定义这样一个方法,但似乎不知道如何去做


以我尝试的方式自定义会话的理想方法是什么?

这将不允许您更改会话。但是,如果您需要使用自定义参数派生一个新的*discordgo.Session,您可以执行以下类似操作

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)
}

我不知道该库的上下文,所以我不确定我在这里写的内容是否对您有意义:但通过查看API,SessionFunc是一个functoken字符串*discordgo.Session,error,即一个接收字符串并返回会话和错误的函数。所以你可以这样做来覆盖它:

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
}
代码显然非常通用,但主要思想是您需要使用确切的头定义该函数,并实现它。例如,我不知道如何计算令牌参数或创建discordgo.Session。或者如何使用SessionFunc配置TrackRoles或TrackPresence值。这只适用于该库,但我想这对你比我更有意义:

您还可以在其他地方使用该确切的头定义一个常规函数:

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
}
两种方法的工作方式相同


反射[几乎]从来都不是做这些事情的推荐方式,如果库创建者将这些属性设置为私有,则不应从外部更改/访问它们。

该代码中没有SessionFunc处理会话。bareSession设置一次,从那时起,它只能从中读取。它似乎有意不被触碰。使用“反射”和“不安全”可以设置字段,但这是无论如何都应该避免的。。。。如果没有任何其他第三方软件包允许你做你需要的事情,你可以选择分叉项目并简单地导出bareSession字段。我想学习做这件事的最佳实践方法-不是这样。最好的做法是不要修补未报告的成员。这就是为什么存在未报告的成员。这非常有帮助,谢谢。有没有办法扩展SessionFunc而不必复制代码中的逻辑?我刚刚检查了dshardmanager的代码,有一个函数stdsSessionFunc,它包含SessionFunc的默认实现,因此您可以在自己的自定义函数中调用它,即s,err:=manager.stdsSessionFuncToken。。。