英文:
Golang - embed.FS pass argument
问题
我需要修改代码片段,需要使用参数而不是在go:embed中使用硬编码的路径。
我的代码:
package main
import (
    "embed"
    "log"
    
    "github.com/golang-migrate/migrate/v4/source/iofs"
)
// 我需要将`migrations/*.sql`的路径作为参数传递给`migrate`函数,而不是使用硬编码的`migrations/*.sql`
//go:embed migrations/*.sql
var fs embed.FS
func main() {
    const path = "migrations/*.sql"
    if err := migrate(path); err != nil {
        log.Fatal(err)
    }
    log.Println("done")
}
func migrate(path string) error {
    d, err := iofs.New(fs, "migrations")
	if err != nil {
		return err
	}
    
    // 其余的代码...
    return nil
}
我已经尝试使用os.DirFS,但是这个函数的结果只包含dir参数的数据,而不包含migrations/*.sql文件夹中的实际文件。
英文:
I need to modify fragment of code which needs to take argument instead of use hardcoded path in go:embed
My code:
package main
import (
    "embed"
    "log"
    
    "github.com/golang-migrate/migrate/v4/source/iofs"
)
// Instead of use hardcoded `migrations/*.sql` I need to pass 
// `path` to `migrations/*.sql` as a argument to `migrate` function
//go:embed migrations/*.sql
var fs embed.FS
func main() {
    const path = "migrations/*.sql"
    if err := migrate(path); err != nil {
        log.Fatal(err)
    }
    log.Println("done")
}
func migrate(path string) error {
    d, err := iofs.New(fs, "migrations")
	if err != nil {
		return err
	}
    
    // rest of the code...
    return nil
}
I already tried to use os.DirFS however result of this function only contains data with dir parameter without actual files from folder migrations/*.sql
答案1
得分: 1
我不完全确定我理解了问题。您创建了一个包含多个文件的嵌入式文件系统(包含migrations目录中匹配*.sql的所有文件)。您可以通过名称从这个嵌入式文件系统中加载文件。
假设您的migrations目录如下所示:
migrations/
├── bar.sql
└── foo.sql
其中foo.sql包含this is foo.sql,bar.sql类似。
如果我们编写以下代码:
func main() {
  const path = "migrations/foo.sql"
  if err := migrate(path); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}
func migrate(path string) error {
  data, err := fs.ReadFile(path)
  if err != nil {
    panic(err)
  }
  fmt.Println(string(data))
  // 其余的代码...
  return nil
}
您将得到输出:
this is foo.sql
如果您想遍历嵌入式文件系统中的文件,可以使用ReadDir方法:
func main() {
  const path = "migrations"
  if err := migrate(path); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}
func migrate(path string) error {
  items, err := fs.ReadDir(path)
  if err != nil {
    panic(err)
  }
  for _, ent := range items {
    fmt.Println(ent.Name())
  }
  // 其余的代码...
  return nil
}
这将打印:
bar.sql
foo.sql
这对您有帮助吗?
英文:
I'm not entirely sure I understand the question. You've created an embedded filesystem that contains multiple files (everything matching *.sql in the migrations directory). You can load files from this embedded filesystem by name.
Let's assume that your migrations directory looks like:
migrations/
├── bar.sql
└── foo.sql
Where foo.sql contains this is foo.sql, and similarly for bar.sql.
If we write code like this:
func main() {
  const path = "migrations/foo.sql"
  if err := migrate(path); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}
func migrate(path string) error {
  data, err := fs.ReadFile(path)
  if err != nil {
    panic(err)
  }
  fmt.Println(string(data))
  // rest of the code...
  return nil
}
You'd get the output:
this is foo.sql
If you want to iterate over files in your embedded filesystem, you can use the ReadDir method:
func main() {
  const path = "migrations"
  if err := migrate(path); err != nil {
    log.Fatal(err)
  }
  log.Println("done")
}
func migrate(path string) error {
  items, err := fs.ReadDir(path)
  if err != nil {
    panic(err)
  }
  for _, ent := range items {
    fmt.Println(ent.Name())
  }
  // rest of the code...
  return nil
}
This would print:
bar.sql
foo.sql
Does that help?
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论