请问老师 用户信息解析器(下) 为什么要单独声明 name 来 接收 m[2]的值呢

来源:15-9 用户信息解析器(下)

gsdad_white

2020-04-28

代码如下:

for _, singleArray := range matchArray {
	// 数组内容: [完整连接, 连接, 用户名]

	parseResult.Items = append(parseResult.Items, "User "+string(singleArray[2]))
	parseResult.Requests = append(parseResult.Requests, os.Request{
		Url: string(singleArray[1]),
		ParseFunc: func(content []byte) os.ParseResult {
			return UserParseResult(content, string(singleArray[2]))
		},
	})
}

老师原本的 变量 m 就是我这里的 singleArray, 我的问题是 单独提取出来 放在 for 里面直接在 for 里面使用 我感觉并没有区别呢?

老师在视频中提到 ParseFunc 是会在 城市 的 循环完全退出, 才会去执行这个函数, 此时的 singleArray 早就不是当时 for 想要的, 而是最后一个.

那既然都是最后才执行, 那单独声明出来就能拿到(虽然我试了可以, 但还是很疑惑)?

写回答

2回答

ccmouse

2020-05-01

我做了个示例:https://play.studygolang.com/p/DcG8BBbiQMt 

package main

import "fmt"

func createPrintFunc(v int) func() {
  return func() {
     fmt.Println("fmt.Println in function with v copied as arg", v)
  }
}

func main() {
  a := []int{1, 2, 3, 4, 5}
  var funcArr []func()
  for _, v := range a {
     fmt.Println("fmt.Println", v) // 这里立刻打印出v,是对的

     funcArr = append(funcArr, func() {
        fmt.Println("fmt.Println in function", v) // 这里做了一个函数,在循环结束之后再执行,所以打印出来的都是5
     })

     vv := v // 这里复制了一份到vv,vv的作用域是{}内,因此有5份拷贝,是对的。
     funcArr = append(funcArr, func() {
        fmt.Println("fmt.Println in function with copy of v", vv)
     })

     funcArr = append(funcArr, createPrintFunc(v)) // 这里通过传参的方式,虽然参数在createPrintFunc里面也叫v,但是其实是v的一份拷贝。
  }
  for _, f := range funcArr {
     f()
  }
}


4
3
huochaiqiang
回复
ccmouse
谢谢,老师。
2020-12-31
共3条回复

ccmouse

2020-05-01

这个singleArray的生命周期是整个for语句。他会依次被赋值为matchArray中的每一个元素,而在整个for中,singleArray只有一份。

这些返回的函数中有使用singleArray[2],但是这只是一个函数闭包的生成,并没有去执行singleArray[2],执行的时间点在后面这个request被执行的时候,此时这个for早已执行完,singleArray早已经是最后一个元素。

但当我们说name:=singleArray[2]的时候,这个name的作用域是这个for的大括号内部。我们这个matchArray有多少个元素,就会有多少个name,而不像singleArray只有一个。所以用了name就可以解决这个问题。


0
0

Google资深工程师深度讲解Go语言 由浅入深掌握Go语言

语法+分布式爬虫实战 为转型工程师量身打造

5995 学习 · 1909 问题

查看课程