如何比较两个函数是否为同一个函数?

来源:14-3 新爬虫的选择

乐只君子

2020-01-30

在 xcar 中的 ParseCarList 中 可以分析出 CarList 的 Request 和 CarModel 的 Request

于是在写单元测试时,有了如下的代码片段:

var actualModelURLs, actualListURLs []string
	for _, request := range actualParseCarListResult.Requests {
		switch request.ParserFunc {
		case ParseCarModel:
			actualModelURLs = append(actualModelURLs, request.URL)
		case ParseCarList:
			actualListURLs = append(actualListURLs, request.URL)
		default:
			t.Errorf("unexcept parse function")
		}
	}

在运行时发现,func 只能和 nil 比较。通过查资料,貌似这里只能用到反射?不确定是否有更好的写法,烦请老师和大家解答疑惑


完整代码片段

package parser

import (
	"io/ioutil"
	"testing"
)

var exceptModelURLs = []string{
	"https://newcar.xcar.com.cn/3428/",
	"https://newcar.xcar.com.cn/3796/",
	"https://newcar.xcar.com.cn/4063/",
	"https://newcar.xcar.com.cn/189/",
	"https://newcar.xcar.com.cn/957/",
	"https://newcar.xcar.com.cn/3866/",
	"https://newcar.xcar.com.cn/3406/",
	"https://newcar.xcar.com.cn/4086/",
	"https://newcar.xcar.com.cn/22/",
	"https://newcar.xcar.com.cn/4116/",
	"https://newcar.xcar.com.cn/63/",
	"https://newcar.xcar.com.cn/3226/",
	"https://newcar.xcar.com.cn/10/",
	"https://newcar.xcar.com.cn/4475/",
	"https://newcar.xcar.com.cn/1468/",
	"https://newcar.xcar.com.cn/306/",
	"https://newcar.xcar.com.cn/4039/",
	"https://newcar.xcar.com.cn/3028/",
	"https://newcar.xcar.com.cn/3563/",
	"https://newcar.xcar.com.cn/2805/",
}

var exceptListURLs = []string{
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-6-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-8-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-11-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-13-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-12-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-14-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-10-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-9-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-1-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-2-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-3-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-4-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-5-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-7-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-15-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-16-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-17-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-18-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-19-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-4-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-3-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-7-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-8-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-12-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-13-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-0-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-3-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-4-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-2-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-21-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-23-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-22-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-6-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-0-0/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-0-3/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-0-2/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-2-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-1-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-1-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-2-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-3-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-4-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-5-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-6-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-2-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-4-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-5-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-1-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-3-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-6-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-7-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-0-8-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-9-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-1-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-2-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-3-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-4-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-5-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-6-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-7-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-8-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-7-0-0-0-0-1/",
	"https://newcar.xcar.com.cn/car/0-0-0-0-0-0-6-0-0-0-0-1/",
}

func TestParseCarList(t *testing.T) {
	contents, err := ioutil.ReadFile("./carlist_test_data.html")
	if err != nil {
		panic(err)
	}

	actualParseCarListResult := ParseCarList(contents)

	// 重点 重点 重点
	var actualModelURLs, actualListURLs []string
	for _, request := range actualParseCarListResult.Requests {
		switch request.ParserFunc {
		case ParseCarModel:
			actualModelURLs = append(actualModelURLs, request.URL)
		case ParseCarList:
			actualListURLs = append(actualListURLs, request.URL)
		default:
			t.Errorf("unexcept parse function")
		}
	}
	// -------------

	if len(exceptModelURLs) != len(actualModelURLs) {
		t.Errorf("except list length: %d, but got actual: %d",
			len(exceptModelURLs), len(actualModelURLs))
	}
	for i := range actualModelURLs {
		if exceptModelURLs[i] != actualModelURLs[i] {
			t.Errorf("model url expected: \"%s\", actual: \"%s\"",
				exceptModelURLs[i], actualModelURLs[i])
		}
	}

	if len(exceptListURLs) != len(actualListURLs) {
		t.Errorf("except list length: %d, but got actual: %d",
			len(exceptListURLs), len(actualListURLs))
	}
	for i := range actualListURLs {
		if exceptListURLs[i] != actualListURLs[i] {
			t.Errorf("model url expected: \"%s\", actual: \"%s\"",
				exceptListURLs[i], actualListURLs[i])
		}
	}
}

我不确定这种写法是否正确

写回答

1回答

ccmouse

2020-02-02

这里不建议使用反射来判断。我们可以在返回的request类型里加上一个叫做Name或者Type的字段来人工标识。

0
2
乐只君子
非常感谢!也和其他小伙伴讨论了~后续这里可以将 request 改造为 interface
2020-03-15
共2条回复

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

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

5995 学习 · 1909 问题

查看课程