1

I have interface that requires its implementor to have Click method. However, the type FakeTicker that implements this interface also implements Tick method in addition to Click method.

package main



type Ticker interface{  
  Click() string 
}

type FakeTicker struct{ 
   val string }

func (f FakeTicker) Click() string {    
   return f.val 
}

func (f FakeTicker) Tick() int {    return 1 }

func main() {   
  var clocker Ticker    
  clocker = FakeTicker{"Val"}   
  clocker.Tick()    
}

Here I get the following error "clocker.Tick undefined (type Ticker has no field or method Tick)"

I understand that the interface only has method Click() but since FakeWriter is implementing the interface, Shouldn't it be able to call its own method Tick()?

p-ray
  • 49
  • 6
  • @p-ray *"Shouldn't it be able to call its **own** method Tick()?"* It should be able and it also is able. The error is not from *it* not being able to call `Tick` but from the *"user"* of `clocker` not being able to call `Tick`. – mkopriva Feb 14 '18 at 20:12
  • @mkopriva As mentioned in the accepted answer, I think it needs to be converted to implementing struct. – p-ray Feb 15 '18 at 23:16
  • What I meant by my comment is that `FakeTicker` can call its *own* `Tick` method, for example from inside of its *own* `Click` method. `func (f FakeTicker) Click() string { f.Tick(); return f.val }`. I'm just being a little pedantic here, feel free to ignore me. – mkopriva Feb 15 '18 at 23:22

2 Answers2

4

You would need to convert the interface{} to FakeTicker

package main

type Ticker interface {
    Click() string
}

type FakeTicker struct {
    val string
}

func (f FakeTicker) Click() string {
    return f.val
}

func (f FakeTicker) Tick() int { return 1 }

func main() {
    var clocker Ticker
    clocker = FakeTicker{"Val"}
    fakeTicker := clocker.(FakeTicker)
    fakeTicker.Tick()
}
Oleg Sklyar
  • 9,834
  • 6
  • 39
  • 62
vedhavyas
  • 1,101
  • 6
  • 12
1

I understand that the interface only has method Click() but since FakeWriter is implementing the interface, Shouldn't it be able to call its own method Tick()?

Since your clocker variable is defined as the Ticker interface, you only have the methods defined on that interface. If you would like to access the Tick method, you will have to change to the FakeTicker type.

In this case, you can use type assertion.

func main() {   
    var clocker Ticker    
    clocker = FakeTicker{"Val"}
    clocker.Click()
    fake := clocker.(FakeTicker)
    fake.Tick()    
}

You should note that the type assertion will cause a panic when the assertion fails if you don't use the version with two return types (fake, ok := clocker.(FakeTicker)).

Gavin
  • 4,365
  • 1
  • 18
  • 27