News for hackers. Stuff that matters.
Re:Four years of Go by venuzr on Sunday November 10, 2013 @10:02PM (#6709690)
That was my initial struggle as well coming into Go (I have worked for several years in C# & Java). You learn to work around this limitation using interfaces for both function parameters and return types. Frankly, I have had to do a little more explicit typecasting that I would have liked (going from interfaces to the actual type) but it is ok.
Re:Four years of Go by grey-area on Monday November 11, 2013 @05:18AM (#6710884)
Isn't the idea behind interfaces that you add whatever methods you need to use to the interface? If that's the case you don't need or want to cast, you can just assume that the object given to you conforms to that interface...
Re:Four years of Go by alok-g on Sunday November 10, 2013 @11:09PM (#6709905)
Are you saying that making sure the type is correct (just before the cast) becomes the programmer's responsibility? How often does this happen?
Re:Four years of Go by venuzr on Monday November 11, 2013 @08:12AM (#6711391)
Nope. This mostly becomes a problem if you like to be DRY and try to replace generics (type T) kind of functionality with interfaces. For e.g., I have a method, which does the classic, lookup from cache first before hitting the actual db. In C#, you can use

  public T Get<T>(int id, string cacheKey) {

  }
When I consume it and say Get for User object, I expect an User object as I already know it's type.

In Go, you have to return an interface (and ideally an error)

Here would be the equivalent,

  v, err := s.Get(id int, cacheKey string)
  if err != nil {
           //Handle error here
  }
  if v == nil || v.(*models.User) == nil {
		return nil, http.StatusNotFound
  }
Its a bit more code, but on the flip side, it gets you thinking as a client of all the things that can go wrong with your code
Re:Four years of Go by quarterto on Monday November 11, 2013 @07:25AM (#6711243)
This is called a type assertion in Go. Whenever you ask for something as an interface but want to use the type's own method, you have to make a type assertion.

  interface Fooer {
    func Foo()
  }

  type Bar struct {}

  func (s Bar) Foo() {}
  func (s Bar) Baz() {}

  func DoFoo(f Fooer) {
    f.Foo() // fine
    // f.Baz() compile error
    f.(Bar).Baz() // fine
  }
Re:Four years of Go by grey-area on Monday November 11, 2013 @02:01PM (#6713234)
Isn't the entire point of an interface to communicate the behaviour expected by the function though?

If you want a Bar specifically (as the DoFoo code does above), it should take a Bar as an argument.

If you want to accept any struct that satisfies Fooer, add all the methods to Fooer that you need them to satisfy...

Doing otherwise is just subverting the type system and you might as well use a blank interface and effectively have no type checking on your input - if you require a Fooer and then typecast someone might pass a Fooer and get a nasty surprise when it doesn't work.