本文同時(shí)發(fā)布在個(gè)人博客chinazt.cc 和 gitbook

今日看到了一個(gè)有趣的golang項(xiàng)目--kolpa(https://github.com/malisit/kolpa)。 這個(gè)項(xiàng)目可以用來生成偽造的姓名,地址,時(shí)間,User-Agent等等信息,在需要大量隨機(jī)數(shù)據(jù)的測(cè)試環(huán)境中非常合適。

點(diǎn)擊fork之后,放在本地環(huán)境中build,run結(jié)果失敗。運(yùn)行項(xiàng)目中提供的demo也失敗,按道理來說官方提供的demo應(yīng)該都會(huì)成功,而且自己也沒有修改任何一行代碼,失敗是不科學(xué)的。

所以只能剖解代碼,查找失敗原因。

一查不知道,原來此項(xiàng)目需要依賴各個(gè)語言環(huán)境下的模板文件,而模板文件都放在項(xiàng)目的data目錄中。 在代碼中,通過硬編碼來確定模板文件位置:

// Reads the file "fName" and returns its content as a slice of strings.func (g *Generator) fileToSlice(fName string) ([]string, error) {var res []stringpath := os.Getenv("GOPATH") + "/src/github.com/malisit/kolpa/data/" + g.Locale + "/" + fName
file, err := os.Open(path)if err != nil {return nil, err
}defer file.Close()

scanner := bufio.NewScanner(file)for scanner.Scan() {
res = append(res, scanner.Text())
}if err := scanner.Err(); err != nil {//log.Println("Inteded generation is not valid for selected language. Switching to en_US.")return g.fileToSlice(fName)
}return res, nil}

因?yàn)槲沂峭ㄟ^fork,然后clone到本地的方式來運(yùn)行demo,本地此時(shí)packge路徑已經(jīng)不是上面的路徑了,所以導(dǎo)致運(yùn)行失敗。 很難說這是一個(gè)bug,但的確影響到了程序運(yùn)行。 所以說不良的代碼風(fēng)格更為恰當(dāng)吧。

既然找到了問題,那下一步就是如何解決問題。 應(yīng)該如何在Runtime時(shí)實(shí)時(shí)獲取package位置呢?

說到Runtime,那么一定就少不了Reflect package。

Package reflect implements run-time reflection, allowing a program