Pointer problem

I have this code but I don’t understand one thing. I created a value of Circle struct and can call area() method on it ( c1.area() ) and it works. but when using the totalArea() method, it specifically asks to pass a pointer ( *c1) and not c1. My question is although area method needs a pointer but value c1 works with it since Go automatically converts it but why I wanna use the same value as shape and pass it to totalArea method, it is nagging?

    package main

import (
"fmt"
"math"
)

func distance(x1, y1, x2, y2 float64) float64 {
a := x2 - x1
b := y2 - y1
return math.Sqrt(a*a + b*b)
}

type Shape interface {
area() float64
}
type Circle struct {
x float64
y float64
r float64
}

func circleArea(c *Circle) float64 {
return math.Pi * c.r * c.r
}
func (c *Circle) area() float64 {
return math.Pi * c.r * c.r
}

type Rectangle struct {
x1, y1, x2, y2 float64
}

func (r *Rectangle) area() float64 {
l := distance(r.x1, r.y1, r.x1, r.y2)
w := distance(r.x1, r.y1, r.x2, r.y1)
return l * w
}

func totalArea(shapes ...Shape) float64 {

var area float64
for _, s := range shapes {
	fmt.Printf("%T\n", s)
	area += s.area()
}
return area
}

func main() {
c1 := Circle{x: 0, y: 0, r: 5}
r1 := Rectangle{0, 0, 10, 10}
fmt.Println(totalArea(c1, r1))
//fmt.Println(c1.area())
//fmt.Printf("%T", c1)
}

If you want use pointers - just do it:

	c1 := &Circle{x: 0, y: 0, r: 5}
	r1 := &Rectangle{0, 0, 10, 10}

Or so:

	c1 := Circle{x: 0, y: 0, r: 5}
	r1 := Rectangle{0, 0, 10, 10}
	fmt.Println(totalArea(&c1, &r1))

Thnaks for the reply. Actually my question is not how to use pointers. I wanna know why is it legal to say c1.area() although area() method receives a pointer as receiver but totalArea() method does not work with c1 but only &c1. In the former, Go can automatically convert c1 to &c1 but in the latter case it gives me an error.

c1.area() works because the compiler knows area requires a pointer receiver and it can unambiguously translate the call to (&c1).area().

You can’t pass the value into totalArea because the language always passes parameters by value (when you want to pass a “reference” to a value as a function parameter, you get its address and pass that address by value). You need to explicitly take the address because Circle doesn’t implement Shape, only *Circle does.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.