英文:
Getting an "undefined: distance" error from Go compiler
问题
我是一名经验丰富的“老派”程序员,但在Go语言方面是个初学者。我正在阅读《CreateSpace: An Introduction to Programing in Go》一书。在第9章的第3个问题中,任务是向用户定义的Shape接口添加一个新的方法。在本章中,接口已经逐步构建起来,以下是我目前的代码:
package main
import (
	"fmt"
	"math"
)
type Shape interface {
	area() float64
	perimeter() float64
}
type Distance struct {
	x1, y1, x2, y2 float64
}
func (d *Distance) distance() float64 {
	a := d.x2 - d.x1
	b := d.y2 - d.y1
	return math.Sqrt(a*a + b*b)
}
type Rectangle struct {
	x1, y1, x2, y2 float64
}
func (r *Rectangle) area() float64 {
	l := distance(r.x1, r.y1, r.x2, r.y1)
	w := distance(r.x1, r.y1, r.x1, r.y2)
	return l * w
}
type Circle struct {
	x, y, r float64
}
func (c *Circle) area() float64 {
	return math.Pi * c.r * c.r
}
type Perimeter struct {
	x1, y1, x2, y2 float64
}
func (p *Perimeter) perimeter() float64 {
	s1 := distance(p.x1, p.y1, p.x1, p.y2)
	s2 := distance(p.x1, p.y2, p.x2, p.y2)
	s3 := distance(p.x2, p.y2, p.x2, p.y1)
	s4 := distance(p.x2, p.y1, p.x1, p.y1)
	return s1 + s2 + s3 + s4
}
func main() {
	d := new(Distance)
	d.x2, d.y2, d.x1, d.y1 = 0, 0, 10, 10
	p := new(Perimeter)
	p.x1, p.y1 = 0, 0
	p.x2, p.y2 = 10, 10
	fmt.Println(p.perimeter())
	r := new(Rectangle)
	r.x1, r.y1 = 0, 0
	r.x2, r.y2 = 10, 10
	fmt.Println(r.area())
	c := Circle{0, 0, 5}
	fmt.Println(c.area())
}
问题是我得到了以下错误(来自编译器?):
# command-line-arguments
.\interface.go:25: undefined: distance
.\interface.go:26: undefined: distance
.\interface.go:42: undefined: distance
.\interface.go:43: undefined: distance
.\interface.go:44: undefined: distance
.\interface.go:45: undefined: distance
我已经花了很多时间仔细阅读章节内容,并努力思考这个“undefined: distance”错误可能意味着什么,但迄今为止没有成功。
正如你所看到的,我定义了一个“Distance结构体”,创建了一个名为d的新实例,并使用.运算符初始化了它的字段,并创建了一个distance()函数,但显然,我没有理解一些相关的信息。
英文:
I'm a seasoned "old school" programmer, but a rank beginner with Go. I'm making my way through the "CreateSpace: An Introduction to
Programing in Go" book.  On p. 111, the third of Chapter 9's Chapter Problems, the task is to add a new method to the user-defined Shape interface.  The interface has been built up over the course of the chapter and here's what I have so far:
package main
import (
"fmt"
"math"
)
type Shape interface {
area() float64
perimeter() float64
}
type Distance struct {
x1, y1, x2, y2 float64
}
func (d *Distance) distance() float64 {
a := d.x2 - d.x1
b := d.y2 - d.y1
return math.Sqrt(a*a + b*b)
}
type Rectangle struct {
x1, y1, x2, y2 float64
}
func (r *Rectangle) area() float64 {
l := distance(r.x1, r.y1, r.x2, r.y1)
w := distance(r.x1, r.y1, r.x1, r.y2)
return l * w
}
type Circle struct {
x, y, r float64
}
func (c *Circle) area() float64 {
return math.Pi * c.r * c.r
}
type Perimeter struct {
x1, y1, x2, y2 float64
}
func (p *Perimeter) perimeter() float64 {
s1 := distance(p.x1, p.y1, p.x1, p.y2)
s2 := distance(p.x1, p.y2, p.x2, p.y2)
s3 := distance(p.x2, p.y2, p.x2, p.y1)
s4 := distance(p.x2, p.y1, p.x1, p.y1)
return s1 + s2 + s3 + s4
}
func main() {
d := new(Distance)
d.x2, d.y2, d.x1, d.y1 = 0, 0, 10, 10
p := new(Perimeter)
p.x1, p.y1 = 0, 0
p.x2, p.y2 = 10, 10
fmt.Println(p.perimeter())
r := new(Rectangle)
r.x1, r.y1 = 0, 0
r.x2, r.y2 = 10, 10
fmt.Println(r.area())
c := Circle{0, 0, 5}
fmt.Println(c.area())
}
The problem is that I am getting the following error (from the compiler?):
user@pc /c/Go/src/golang-book/chapter9/chapterProblems
$ go run interface.go
# command-line-arguments
.\interface.go:25: undefined: distance
.\interface.go:26: undefined: distance
.\interface.go:42: undefined: distance
.\interface.go:43: undefined: distance
.\interface.go:44: undefined: distance
.\interface.go:45: undefined: distance
I've spent a good amount of time doing my "due diligence" hereto pertaining by rereading the chapter text and thinking hard about what this
"undefined: distance" error might mean, but so far to no avail.
As you can see, I have defined a "Distance struct", created a new() instance of
it called d, initialized its fields with the . operator, and created a distance() func, but, clearly, I'm not grokking some relevant piece(s) of information.
答案1
得分: 2
你没有一个名为distance的函数。它是*Distance类型的方法。你需要先创建一个*Distance,然后调用该方法。
d := &Distance{r.x1, r.y1, r.x2, r.y1}
l := d.distance()
我建议你从Effective Go开始。这是一个非常好的介绍,适合“经验丰富的程序员”。
英文:
You don't have a function called distance. It's a method of the type *Distance. You need to create a *Distance first, and then call the method.
d := &Distance{r.x1, r.y1, r.x2, r.y1}
l := d.distance()
I'd suggest starting with Effective Go. It's a very good introduction into the language for "a seasoned programmer".
答案2
得分: 1
你在这里定义的函数:
func (d *Distance) distance() float64 {
    a := d.x2 - d.x1
    b := d.y2 - d.y1
    return math.Sqrt(a*a + b*b)
}
是 Distance 对象的一个方法。看起来你想在这里创建一个新的 Distance 实例:
func (r *Rectangle) area() float64 {
    l := distance(r.x1, r.y1, r.x2, r.y1)
    w := distance(r.x1, r.y1, r.x1, r.y2)
    return l.distance() * w.distance()
}
但实际上你正在尝试调用一个名为 distance 的函数。
你想要的是:
func (r *Rectangle) area() float64 {
    l := &Distance{r.x1, r.y1, r.x2, r.y1}
    w := &Distance{r.x1, r.y1, r.x1, r.y2}
    return l.distance() * w.distance()
}
英文:
Your function defined here:
func (d *Distance) distance() float64 {
a := d.x2 - d.x1
b := d.y2 - d.y1
return math.Sqrt(a*a + b*b)
}
is a method on the Distance object. It looks like you're trying to create a new Distance instance here:
func (r *Rectangle) area() float64 {
l := distance(r.x1, r.y1, r.x2, r.y1)
w := distance(r.x1, r.y1, r.x1, r.y2)
return l.distance() * w.distance()
}
but what you're actually doing is trying to call a function called distance.
You want
func (r *Rectangle) area() float64 {
l := &Distance{r.x1, r.y1, r.x2, r.y1}
w := &Distance{r.x1, r.y1, r.x1, r.y2}
return l.distance() * w.distance()
}
答案3
得分: 1
感谢 @Ainar-G 和 @Momer!在我调整好了思路之后(还得修复了几个自己造成的语法错误),以下代码可以正常运行:
package main
import ("fmt"; "math")
type Shape interface {
    area() float64
    perimeter() float64
}
type Distance struct {
    x1, y1, x2, y2 float64
}
func distance(x1, y1, x2, y2 float64) float64 {
    a := x2 - x1
    b := y2 - y1
    return math.Sqrt(a*a + b*b)
}
type Rectangle struct {
    x1, y1, x2, y2 float64
}
func (r *Rectangle) area() float64 {
    l  := distance(r.x1, r.y1, r.x2, r.y1)
    w := distance(r.x1, r.y1, r.x1, r.y2)
    return l * w
}
type Circle struct {
    x, y, r float64
}
func (c *Circle) area() float64 {
    return math.Pi * c.r*c.r
}
type Perimeter struct {
    x1, y1, x2, y2 float64
}
func (p *Perimeter) perimeter() float64 {
    s1 := distance(p.x1, p.y1, p.x1, p.y2)
    s2 := distance(p.x1, p.y2, p.x2, p.y2)
    s3 := distance(p.x2, p.y2, p.x2, p.y1)
    s4 := distance(p.x2, p.y1, p.x1, p.y1)
    return s1 + s2 + s3 + s4
}
func main() {
    d := new(Distance)
    d.x1, d.y1, d.x2, d.y2 = 0, 0, 10, 10
    p := new(Perimeter)
    p.x1, p.y1, p.x2, p.y2 = 0, 0, 10, 10
    fmt.Println(p.perimeter())
    r := new(Rectangle)
    r.x1, r.y1 = 0, 0
    r.x2, r.y2 = 10, 10
    fmt.Println(r.area())
    c := new(Circle)
    c.x, c.y, c.r = 0, 0, 5
    fmt.Println(c.area())
}
以下是运行结果:
David Bailey@DAVIDBAILEY-PC /c/Go/src/golang-book/chapter9/chapterProblems
$ go run interface.go
40
100
78.53981633974483
David Bailey@DAVIDBAILEY-PC /c/Go/src/golang-book/chapter9/chapterProblems
$
再次感谢你。
英文:
thanks @Ainar-G and @Momer! After I got my "mind right" (had to fix a couple more self-inflicted syntax errors), the following worked:
<pre><code>
package main
import ("fmt"; "math")
type Shape interface {
area() float64
perimeter() float64
}
type Distance struct {
x1, y1, x2, y2 float64
}
func distance(x1, y1, x2, y2 float64) float64 {
a := x2 - x1
b := y2 - y1
return math.Sqrt(a*a + b*b)
}
type Rectangle struct {
x1, y1, x2, y2 float64
}
func (r *Rectangle) area() float64 {
l  := distance(r.x1, r.y1, r.x2, r.y1)
w := distance(r.x1, r.y1, r.x1, r.y2)
return l * w
}
type Circle struct {
x, y, r float64
}
func (c *Circle) area() float64 {
return math.Pi * c.r*c.r
}
type Perimeter struct {
x1, y1, x2, y2 float64
}
func (p *Perimeter) perimeter() float64 {
s1 := distance(p.x1, p.y1, p.x1, p.y2)
s2 := distance(p.x1, p.y2, p.x2, p.y2)
s3 := distance(p.x2, p.y2, p.x2, p.y1)
s4 := distance(p.x2, p.y1, p.x1, p.y1)
return s1 + s2 + s3 + s4
}
func main() {
d := new(Distance)
d.x1, d.y1, d.x2, d.y2 = 0, 0, 10, 10
p := new(Perimeter)
p.x1, p.y1, p.x2, p.y2 = 0, 0, 10, 10
fmt.Println(p.perimeter())
r := new(Rectangle)
r.x1, r.y1 = 0, 0
r.x2, r.y2 = 10, 10
fmt.Println(r.area())
c := new(Circle)
c.x, c.y, c.r = 0, 0, 5
fmt.Println(c.area())
}
<pre><code>
Here's the resulting output:
<pre><code>
David Bailey@DAVIDBAILEY-PC /c/Go/src/golang-book/chapter9/chapterProblems
$ go run interface.go
40
100
78.53981633974483
David Bailey@DAVIDBAILEY-PC /c/Go/src/golang-book/chapter9/chapterProblems
$
<pre><code>
Again, thank you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论