英文:
How to help a Go test find a custom type declaration?
问题
我正在测试Go对Unicode的支持,通过声明一个类型:
type Эксперимент struct {
Строка string
}
在package испытание
中,并尝试在单元测试中导入该类型。然而,当我尝试这样做时,我遇到了一个错误。
跟踪信息:
$ go test
# github.com/mcandre/mcandre/go/испытание_test
./испытание_test.go:10: undefined: Эксперимент
FAIL github.com/mcandre/mcandre/go/испытание [build failed]
源代码:
https://github.com/mcandre/mcandre/tree/master/go/испытание
我是否正确地将我的公共成员大写了?go doc
显示我的结构体被公开列出:
$ go doc
package испытание // import "github.com/mcandre/mcandre/go/испытание"
Package испытание demonstrates Unicode capabilities in Go source code.
type Эксперимент struct { ... }
func Испытание() Эксперимент
也许Go编译器对标记中的Cyrillic字符有问题?
英文:
I'm testing Go's support for Unicode, by declaring a type
type Эксперимент struct {
Строка string
}
in package испытание
, and attempting to import into a unit test. However, when I try this, I get an error.
Trace:
$ go test
# github.com/mcandre/mcandre/go/испытание_test
./испытание_test.go:10: undefined: Эксперимент
FAIL github.com/mcandre/mcandre/go/испытание [build failed]
Source:
https://github.com/mcandre/mcandre/tree/master/go/испытание
Am I capitalizing my public members correctly? go doc
shows my struct being listed publicly:
$ go doc
package испытание // import "github.com/mcandre/mcandre/go/испытание"
Package испытание demonstrates Unicode capabilities in Go source code.
type Эксперимент struct { ... }
func Испытание() Эксперимент
Maybe the Go compiler has a problem with Cyrillic runes in tokens?
答案1
得分: 2
从规范:导出标识符中引用:
> 如果[...]标识符名称的第一个字符是一个Unicode大写字母(Unicode类“Lu”)[...],则该标识符被导出。
西里尔符文没有问题(Go可以很好地处理它们),所有Unicode类“Lu”(大写字母)中的字符都被接受,但是当您导入一个包时,您必须使用包名称来构造限定标识符以引用来自该包的导出标识符。
将您的测试中的这行代码更改为:
wanted := испытание.Эксперимент{Строка: "Испытание!"}
这样做后,测试将通过。运行go test
:
PASS
ok github.com/mcandre/mcandre/go/испытание 0.001s
有关更多信息,请参见相关问题:https://stackoverflow.com/questions/36994445/getting-a-use-of-package-without-selector-error
关于包名称的说明
您需要使用限定标识符,因为您在测试文件中使用了不同的包。您可以选择使用相同的包,这种情况下您不得导入该包(这将导致导入循环,不允许),并且在这种情况下,您不需要使用限定标识符,您可以使用该包的所有导出和非导出标识符。
以下是使用相同包名的测试文件示例:
package испытание
import (
"testing"
)
func TestИспытаниеReturnsИспытание(t *testing.T) {
wanted := Эксперимент{Строка: "Испытание!"}
observed := Испытание()
if observed != wanted {
t.Errorf("испытание.Испытание(): Wanted %s, got %s\n", wanted, observed)
}
}
使用相同包名进行测试称为白盒测试,使用不同包名进行测试称为黑盒测试。您可以在此处阅读更多信息:https://stackoverflow.com/questions/40949178/where-to-put-shared-code-for-tests-in-a-go-package/40949505#40949505
更改名称的说明
通过导入声明,您还可以更改要用于引用导入包标识符的名称;甚至可以在名称的位置使用.
(点),在这种情况下,您可以省略限定标识符中的名称。有关详细信息,请参见:https://stackoverflow.com/questions/29898400/import-struct-from-another-package-and-file-golang/29898669#29898669
英文:
Quoting from the Spec: Exported Identifiers:
> An identifier is exported if [...] the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and [...]
There is nothing wrong with Cyrillic runes (Go handles them well), all characters in the Unicode class "Lu" (Letter, uppercased) are accepted, but when you import a package, you have to use the package name to construct qualified identifiers to refer to exported identifiers from the package.
Change this line in your test:
wanted := Эксперимент{Строка: "Испытание!"}
To this:
wanted := испытание.Эксперимент{Строка: "Испытание!"}
Once you do this it'll pass. Running go test
:
PASS
ok github.com/mcandre/mcandre/go/испытание 0.001s
See this related question for more information: https://stackoverflow.com/questions/36994445/getting-a-use-of-package-without-selector-error
Note on package names
You need to use qualified identifier because you used a different package for your test file. You may choose to use the same package, in which case you must not import the package (it would be an import cycle which is not allowed), and in which case you don't need to use a qualified identifier, you may use all exported and unexported identifiers of the package.
This is how the test file would look like with the same package:
package испытание
import (
"testing"
)
func TestИспытаниеReturnsИспытание(t *testing.T) {
wanted := Эксперимент{Строка: "Испытание!"}
observed := Испытание()
if observed != wanted {
t.Errorf("испытание.Испытание(): Wanted %s, got %s\n", wanted, observed)
}
}
Using the same package name is called white-box testing, using a different package name is called black-box testing. You can read more about it here: https://stackoverflow.com/questions/40949178/where-to-put-shared-code-for-tests-in-a-go-package/40949505#40949505
Note on changing the name
With the import declarations, you can also change the name you want to use to refer to the imported package's identifiers; you can even use a .
(dot) in place of the name, in which case you can omit the name from the qualified identifiers. For details, see this: https://stackoverflow.com/questions/29898400/import-struct-from-another-package-and-file-golang/29898669#29898669
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论