Golang中如何扩展另一个包的函数

Golang中如何扩展另一个包的函数 我正在使用一个从环境变量读取配置的包,如下所示:

func New() (*LLM, error) {
	token := os.Getenv(tokenEnvVarName)
	if token == "" {
		return nil, ErrMissingToken
	}
	c, err := huggingfaceclient.New(token)
	return &LLM{
		client: c,
	}, err
}

我知道可以修改它,使用 godotenv.env 文件读取密钥,例如:

package main

import (
	"fmt"
	"log"
	"os"

	"github.com/joho/godotenv"
)

func main() {
	err := godotenv.Load() // 将加载 ".env" 文件
	if err != nil {
		log.Fatalf("发生了一些错误。错误:%s", err)
	}

	env := os.Getenv("HUGGINGFACEHUB_API_TOKEN")
	if "" == env {
             log.Fatalf("找不到API")
       }
}

有没有办法通过类似扩展的方式来修改 New() 函数,以便在我的 Go 代码中使用,而不是直接修改包本身的代码?


更多关于Golang中如何扩展另一个包的函数的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

我通过创建一个包装函数解决了这个问题,该函数在调用原始的 New() 函数之前,使用 godotenv 从 .env 文件加载环境变量。

package main

import (
	"fmt"
	"log"

	"github.com/joho/godotenv"
	hf "github.com/tmc/langchaingo/llms/huggingface"
)

func NewWithDotEnv() (*hf.LLM, error) {
	err := godotenv.Load()
	if err != nil {
		return nil, err
	}
	return hf.New()
}

func main() {
	llm, err := NewWithDotEnv()
	if err != nil {
		log.Fatal(err)
	}
	completion, err := llm.Call("What would be a good company name for a company that makes colorful socks?")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(completion)
}

更多关于Golang中如何扩展另一个包的函数的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


可以通过包装函数或使用接口来扩展另一个包的函数。以下是两种常见的方法:

方法1:包装函数

创建一个新的函数,内部调用原包的函数,并在调用前执行额外的逻辑(如加载环境变量)。

package main

import (
    "log"
    "os"
    "originalpackage" // 假设原包名为 originalpackage
    "github.com/joho/godotenv"
)

func NewWithEnv() (*originalpackage.LLM, error) {
    // 加载 .env 文件
    if err := godotenv.Load(); err != nil {
        log.Printf("警告:无法加载 .env 文件: %v", err)
    }
    
    // 调用原包的 New 函数
    return originalpackage.New()
}

方法2:使用接口和依赖注入

如果原包的结构体实现了接口,可以通过自定义实现来扩展功能。

package main

import (
    "log"
    "os"
    "originalpackage"
    "github.com/joho/godotenv"
)

type ConfigReader interface {
    ReadConfig() (string, error)
}

type EnvFileReader struct{}

func (r *EnvFileReader) ReadConfig() (string, error) {
    if err := godotenv.Load(); err != nil {
        return "", err
    }
    token := os.Getenv(tokenEnvVarName)
    if token == "" {
        return "", originalpackage.ErrMissingToken
    }
    return token, nil
}

func NewWithReader(reader ConfigReader) (*originalpackage.LLM, error) {
    token, err := reader.ReadConfig()
    if err != nil {
        return nil, err
    }
    c, err := huggingfaceclient.New(token)
    return &originalpackage.LLM{
        client: c,
    }, err
}

// 使用示例
func main() {
    reader := &EnvFileReader{}
    llm, err := NewWithReader(reader)
    if err != nil {
        log.Fatal(err)
    }
    // 使用 llm
}

方法3:修改环境变量(如果原包只使用 os.Getenv

在调用原包函数前设置环境变量。

package main

import (
    "log"
    "os"
    "originalpackage"
    "github.com/joho/godotenv"
)

func init() {
    // 在程序启动时加载 .env 文件
    if err := godotenv.Load(); err != nil {
        log.Printf("警告:无法加载 .env 文件: %v", err)
    }
}

func main() {
    // 现在可以直接调用原包的 New 函数
    llm, err := originalpackage.New()
    if err != nil {
        log.Fatal(err)
    }
    // 使用 llm
}

这些方法允许你在不修改原包代码的情况下扩展其行为。选择哪种方法取决于具体场景和原包的设计。

回到顶部