I'm using Visual Studio Code with the official Go extension and the official Go tools.
My Go version is go1.19
.
When I rename an interface's function, it doesn't affect its implementations which leads to to compiler errors.
Sample Code:
package main
import "fmt"
type animal interface {
makeSound()
}
type dog struct {
name string
}
func (d *dog) makeSound() {
fmt.Printf("%s: bark! bark!", d.name)
fmt.Println()
}
func main() {
dog1 := &dog{
name: "dog1",
}
patHead(dog1)
}
func patHead(a animal) {
a.makeSound()
}
Output:
dog1: bark! bark!
The Problem:
If I try to rename dog.makeSound()
(e.g. to dog.makeNoise()
), I get the following error:
renaming this method "makeSound" to "makeNoise" would make *project.dog no longer assignable to interface animal (rename project.animal.makeSound if you intend to change both types)
The error makes sense because the programmer might have missed that the struct was implementing an interface, so a recursive rename that affects the interface and other implementations would be unintentional. I don't have a problem with this error.
As the error message instructs, you can rename the interface's function. The rename affects users of that interface:
type animal interface {
makeNoise()
}
func patHead(a animal) {
a.makeNoise()
}
However, it leaves its implementations unaffected, which now generates an error:
type dog struct {
name string
}
func (d *dog) makeSound() {
fmt.Printf("%s: bark! bark!", d.name)
fmt.Println()
}
func main() {
dog1 := &dog{
name: "dog1",
}
patHead(dog1)
}
Error:
cannot use dog1 (variable of type *dog) as animal value in argument to patHead: *dog does not implement animal (missing method makeNoise)
The problem is that now that there is a compiler error, you can't rename the implementation's method to match the interface.
Below is the error when you try to rename dog.makeSound()
to dog.makeNoise()
:
renaming "makeSound" to "makeNoise" not possible because "project" has errors
Renaming interface functions should be as simple as renaming a variable or class function, and Go's default tools handle the latter scenarios very well. However, it doesn't handle the problem stated above.
GoLand (which isn't free) supports renaming interface implementations as documented here, but assuming you can only use free tools, how do you handle this scenario?
Find and Replace isn't safe because it could affect unrelated code, and manually fixing all the compiler errors generated after renaming the interface function is tedious if you have many implementations in your project.
UPDATE:
I submitted a gorename
issue here.
However, I want to keep this question open in case my bug doesn't get fixed and I can accept a solid workaround in the meantime for this common problem in Go.