imported and not used error - go

I can't figure out how to create a package and use it. I'm using liteid and go 1.4.2 but this is all reproduce-able from the command-line. I' able to create the shape package it seems but it doesn't load from the main package.
GOPATH=d:\src\teaching\golang
GOROOT=c:\go
+teaching\golang\pkg
\windows_386
shape.a
\src
\packages
packages.go
\shape
shape.go
go install shape -> generates shape.a
go build packages.go
# packages
d:\src\teaching\golang\src\packages\packages.go:5: imported and not used: "shape"
d:\src\teaching\golang\src\packages\packages.go:8: undefined: Shape
d:\src\teaching\golang\src\packages\packages.go:19: undefined: Circle
shape.go
package shape
import (
"fmt"
)
const (
pi = float64(3.14)
)
type Shape interface {
Area() float64
}
type Circle struct {
x int
y int
radius int
}
func (c *Circle) Area() float64 {
return pi * float64(c.radius*c.radius)
}
func (c Circle) String() string {
return fmt.Sprintf("{x=%d, y=%d, radius=%d}", c.x, c.y, c.radius)
}
packages.go
package main
import (
"fmt"
"shape"
)
func calculateArea(shapes ...Shape) float64 {
sum := float64(0)
for _, v := range shapes {
sum += v.Area()
}
return sum
}
func main() {
circle := Circle{x: 1, y: 2, radius: 2}
fmt.Println(circle, circle.Area(), calculateArea(&circle))
}
Any ideas?

Shape is defined in the shape package. You have to reference it as shape.Shape

Related

Interface vs pointer/value receiver

If I use pointer receiver, the following code has exception at a=v since it is defined on pointer v, it makes sense.
package main
import (
"fmt"
"math"
)
type Abser interface {
Abs(x int) float64 //all types needs to implement this interface
}
type Vertex struct {
X float64
}
func (v *Vertex) Abs(x int) float64 {
return math.Abs(float64(x))
}
func main() {
/*define the interface and assign to it*/
var a Abser
v := Vertex{-3}
a = &v
fmt.Println(a.Abs(-3))
a = v
fmt.Println(a.Abs(-3))
}
But if I change the function of Abs to
func (v Vertex) Abs(x int) float64 {
return math.Abs(float64(x))
}
both a=v and a=&v works, what is the reason behind that?
Understand it like this as I do not have right resources to quote in answer; Go is happy to pass a copy of pointer struct as value when interface is implemented on value, you can check this by printing the address of variable; This is due to the fact that this operation is considered safe and cannot mutate the original value;

Can't access embedded struct when I pass an instance of my outer structinto a slice of an interface, which the outer struct implements

package main
import (
"fmt"
)
type shape struct {
name string
}
type square struct {
shape
length int
}
type twoDimensional interface {
area() int
}
func (s square) area() int {
return s.length * s.length
}
func main() {
s1 := square{
length: 2,
}
s1.name = "spongebob"
allSquares := []twoDimensional{
s1,
}
fmt.Println(allSquares[0].name)
}
This is giving me the following error:
./prog.go:36:27: allSquares[0].name undefined (type twoDimensional has no field or method name)
I'm confused about what's going on here. Type square is embedded with type shape, and type square also implements the twoDimensional interface.
If I pass an instance of square into a slice of twoDimensionals, how come I can no longer access type shape from my square?
The interface itself does not have .name attribute. You need to use type assertion allSquares[0].(square) as the following:
package main
import (
"fmt"
)
type shape struct {
name string
}
type square struct {
shape
length int
}
type twoDimensional interface {
area() int
}
func (s square) area() int {
return s.length * s.length
}
func main() {
s1 := square{
length: 2,
}
s1.name = "spongebob"
allSquares := []twoDimensional{
s1,
}
fmt.Println(allSquares[0].(square).name)
}

How to fix golang too many arguments error

i am using following code...
package main
import (
"fmt"
)
type traingle interface {
area() int
}
type details struct {
height int
base int
}
func (a details) area() int {
s := a.height + a.base
fmt.Println("the area is", s)
return s
}
func main() {
r := details{height: 3, base: 4}
var p1 traingle
p1.area(r)
}
not getting why getting following error
too many arguments in call to p1.area
have (details)
want ()
i am assuming that p1 object of triangle can call area() method with arguments. not getting why it is failing.
The function area takes no arguments in its definition:
area() int
// ...
func (a details) area() int {
Therefor, passing any arguments to it is, as the error says, too many arguments. There is nowhere in the function where it makes use of arguments. It's making all its calculations based on the properties of its receiver, not any arguments. You're also calling it on an uninitialized (nil) interface value. It looks like what you want is probably:
r := details{height: 3, base: 4}
r.area()
Try this:
package main
import (
"fmt"
)
type shape interface {
area() int
}
type traingle struct {
height int
base int
}
func (a traingle) area() int {
return a.height * a.base / 2
}
func main() {
var p1 shape = traingle{height: 3, base: 4}
fmt.Println(p1.area())
}
output:
6
And see this example on shape: https://stackoverflow.com/a/38818437/8208215
I hope this helps.

Methods and receivers in Go

I have problems understanding methods and receivers in Go. Let's say we have this code:
package main
import ("fmt"; "math")
type Circle struct {
x, y, r float64
}
func (c *Circle) area() float64 {
return math.Pi * c.r * c.r
}
func main() {
c := Circle{0, 0, 5}
fmt.Println(c.area())
}
(c *Circle) in the definition of the area function is said to be a receiver and in the main we can call area and pass c by reference without the use of pointers. I can edit the code to the following and it works the same way:
package main
import ("fmt"; "math")
type Circle struct {
x, y, r float64
}
func circleArea(c *Circle) float64 {
return math.Pi * c.r*c.r
}
func main() {
c := Circle{0, 0, 5}
fmt.Println(circleArea(&c))
}
Now is this just a syntactical difference between the two snippets of code or is there something structurally different going on on a deeper level?
The difference isn't just syntax. With a method, your circle type could fulfill an interface, but the function doesn't let you do that:
type areaer interface {
area() float64
}

How to set any value to interface{}

I have following code:
package main
import (
"fmt"
)
type Point struct {
x,y int
}
func decode(value interface{}) {
fmt.Println(value) // -> &{0,0}
// This is simplified example, instead of value of Point type, there
// can be value of any type.
value = &Point{10,10}
}
func main() {
var p = new(Point)
decode(p)
fmt.Printf("x=%d, y=%d", p.x, p.y) // -> x=0, y=0, expected x=10, y=10
}
I want to set value of any type to the value passed to decode function. Is it possible in Go, or I misunderstand something?
http://play.golang.org/p/AjZHW54vEa
Generically, only using reflection:
package main
import (
"fmt"
"reflect"
)
type Point struct {
x, y int
}
func decode(value interface{}) {
v := reflect.ValueOf(value)
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
n := reflect.ValueOf(Point{10, 10})
v.Set(n)
}
func main() {
var p = new(Point)
decode(p)
fmt.Printf("x=%d, y=%d", p.x, p.y)
}
I'm not sure of your exact goal.
If you want to assert that value is a pointer to Point and change it, you can do that :
func decode(value interface{}) {
p := value.(*Point)
p.x=10
p.y=10
}

Resources