你使用的Go版本是什么( go version
)?
$ go version
go1.18
这个问题在最新版本的发布中是否重现?
yes
你正在使用什么操作系统和处理器架构( go env
)?
$ go env
GOHOSTARCH="amd64"
GOOS="linux"
你做了什么?
首先,我在不同的文件夹中创建了两个名为old和new的包,并在每个包中创建了一个文件。
文件内容如下。
// the file in old package
package demo
type Iface interface{
Func()
}
type S struct {}
func (s *S) Func() {}
// the file in new package
package demo
type Iface interface{
Func()
}
type S struct {}
// func (s *S) Func() {}
然后我使用apidiff来比较这两个包。
func ImplementTest() {
// get pkgs in old package
oldDir := "/the/old/package/path"
oldCfg := &packages.Config{
Mode: packages.NeedTypes | packages.NeedName | packages.NeedImports | packages.NeedDeps,
Tests: false,
Dir: oldDir,
}
oldPkgs, err := packages.Load(oldCfg, "./...")
if err != nil {
fmt.Println("packages.Load() error: ", err.Error())
}
// then do same action in new package
// ...
// then use apidiff the diff them
for _, op := range oldPkgs {
for _, np := range newPkgs {
if op.Name == np.Name {
fmt.Println(apidiff.Changes(op.Types, np.Types))
}
}
}
}
你期望看到什么?
Incompatible changes:
- (*S).Func: removed
- (*S): no longer implements Iface
你实际看到了什么?
Incompatible changes:
- (*S).Func: removed
我发现的问题
问题位置
// in file apidiff.go
// line 109 ~ 116
for otn2, nt2 := range d.correspondMap {
if otn1 == otn2 {
continue
}
if types.Implements(otn2.Type(), oIface) && !types.Implements(nt2, nIface) {
d.incompatible(otn2, "", "no longer implements %s", objectString(otn1))
}
}
这段代码只能检查S是否实现了Iface,但不能检查*S是否实现了Iface,这就是为什么我得到的结果不如预期的原因。
这段代码是否应该改为这样?
// in file apidiff.go
// line 109 ~ 116
for otn2, nt2 := range d.correspondMap {
if otn1 == otn2 {
continue
}
if types.Implements(otn2.Type(), oIface) && !types.Implements(nt2, nIface) {
d.incompatible(otn2, "", "no longer implements %s", objectString(otn1))
}
// to check whether *S implements interface
if types.Implements(types.NewPointer(otn2.Type()), oIface) && !types.Implements(types.NewPointer(nt2), nIface) {
d.incompatible(otn2, "", "no longer implements %s", objectString(otn1))
}
}
1条答案
按热度按时间hi3rlvi21#
CC @jba.