将指针传递给bufio.Scanner() [英] Passing a pointer to bufio.Scanner()
问题描述
我尝试的方法是传递一个指向 bufio.Scanner
的指针,但这不起作用。我认为这可能与需要将搜索位置设置回文件的开头有关,但它甚至不是第一次运行,我在文档中找不到这样的参数。我试图创建这个函数,然后通过引用我打算在goroutine中运行的函数来传递结果(现在,我 使用goroutines 只是为了使确定这是完全正常的,而不是)。
这是一个MWE:
// ...包装声明;进口; yada yada
func main(){
// ...验证存储在filePath变量中的文件路径
filePath:=/path/to/file.txt
//获取单词列表扫描器以便在goroutines之间共享
scanner:= getScannerPtr(&filePath)
//传递给函数(现在没有goroutine,我尝试一次解决一个问题)
myfunc(scanner)
}
func getScannerPtr(filePath * string)* bufio.Scanner {
f,err: = os.Open(* filePath)
if err!= nil {
fmt.Fprint(os.Stderr,Error opening file\\\
)
panic(err)
)
推迟f.Close()
扫描器:= bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
返回扫描器
}
func myfunc(scanner * bufio.Scanner){
for scanner.Scan(){
line:= strings.TrimSpace(scanner.Text())
// ...用
}
}
执行某些操作receivi如果我调用 Scan()
,它不会在该块内部对文件的每一行执行任何操作。请记住,我甚至没有使用并发性,这只是我最终想要指出的一个目标,以防影响我需要采用的方法。
- 为什么
Scan()
无法使用? - 如果我打算今后调用
go myfunc(scanner)
,这是一种可行的方法吗?
Scanner
之前,您正在关闭文件: $ b $
func getScannerPtr(filePath * string)* bufio.Scanner {
f,err:= os.Open(* filePath)
如果错误!= nil {
fmt.Fprint(os.Stderr,Error opening file\\\
)
panic(err)
}
推迟f.Close( )//< ---这里
scanner:= bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
返回扫描器//< - 文件被关闭,那么试图读取它的扫描仪将被返回供进一步使用,这将不起作用
}
<因为 Scanner
不公开关闭
,您需要解决此问题;最快的可能是用一些嵌入字段来创建一个简单的自定义类型:
$ p $ type FileScanner struct {
io .Closer
* bufio.Scanner
}
func getScannerPtr(filePath * string)* FileScanner {
f,err:= os.Open(* filePath)
if err!= nil {
fmt.Fprint(os.Stderr,Error opening file \\\
)
panic(err)
}
scanner:= bufio .NewScanner(f)
return& FileScanner {f,scanner}
}
func myfunc(scanner * FileScanner){
defer scanner.Close()
for scanner.Scan(){
line:= strings.TrimSpace(scanner.Text())
// ...用行
}
}
Lest I provide an XY problem, my goal is to share a memory-mapped file between multiple goroutines as recommended. Each goroutine needs to iterate over the file line by line so I had hoped to store the complete contents in memory first to speed things up.
The method I tried is passing a pointer to a bufio.Scanner
, but that is not working. I thought it might be related to needing to set the seek position back to the beginning of the file but it is not even working the very first time and I can find no such parameter in the documentation. My attempt was to create this function then pass the result by reference to the function I intend to run in a goroutine (for right now, I am not using goroutines just to make sure this works outright, which it does not).
Here is a MWE:
// ... package declaration; imports; yada yada
func main() {
// ... validate path to file stored in filePath variable
filePath := "/path/to/file.txt"
// get word list scanner to be shared between goroutines
scanner := getScannerPtr(&filePath)
// pass to function (no goroutine for now, I try to solve one problem at a time)
myfunc(scanner)
}
func getScannerPtr(filePath *string) *bufio.Scanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
return scanner
}
func myfunc(scanner *bufio.Scanner) {
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// ... do something with line
}
}
I'm not receiving any errors, it just is not iterating over the file when I call Scan()
so it never makes it inside that block to do anything with each line of the file. Keep in mind I am not even using concurrency yet, that is just my eventual goal which I want to point out in case that impacts the method I need to take.
- Why is
Scan()
not working? - Is this is a viable approach if I intend to call
go myfunc(scanner)
in the future?
You're closing the file before you ever use the Scanner
:
func getScannerPtr(filePath *string) *bufio.Scanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
defer f.Close() // <--- Here
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
return scanner // <-- File gets closed, then Scanner that tries to read it is returned for further use, which won't work
}
Because Scanner
does not expose Close
, you'll need to work around this; the quickest is probably to make a simple custom type with a couple of embedded fields:
type FileScanner struct {
io.Closer
*bufio.Scanner
}
func getScannerPtr(filePath *string) *FileScanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
scanner := bufio.NewScanner(f)
return &FileScanner{f, scanner}
}
func myfunc(scanner *FileScanner) {
defer scanner.Close()
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// ... do something with line
}
}
这篇关于将指针传递给bufio.Scanner()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!