0

I have defined an interface named session, and I have SessionA and SessionB like this

type Session interface {
    StartSession()
}
type SessionA struct {
    jobs string
}

type SessionB struct {
    foods string
}

func (sessionA *SessionA) StartSession() {
    fmt.Printf("begin to do %s\n", sessionA.jobs)
}

func (sessionB *SessionB) StartSession() {
    fmt.Printf("begin to eat %s\n", sessionB.foods)
}

In my main function I want to define a parameter which can call StartSession automatically

func main() {
    sessionType := 1 // maybe 2, just example
    var s interface{}
    if sessionType == 1 {
        s = SessionA{}
    } else {
        s = SessionB{}
    }
    
    s.StartSession() 
}

but I get this s.StartSession() type interface {} is interface with no methods, my question is how can I use same variable to call different StartSession()

2
  • 5
    var s Session. Define the variable using the correct type. Commented May 16, 2022 at 16:01
  • 1
    you need 2 changes in your code 1) declare the variable s as type Session., ie var s Session 2) you need to assign pointers of SessionA and SessionB to s. ie s = &SessionA{}. The reason being pointer receiver methods won't be in the method set of your normal variable. Commented May 16, 2022 at 18:35

3 Answers 3

2

Two fixes are needed:

  • To call an interface method on some variable, declare the variable as the interface type.
  • The pointer receiver implements the method. Assign pointers to the interface variable.

Here's the code:

var s Session        // Declare variable as Session so we can call StarSession
if sessionType == 1 {
    s = &SessionA{}  // note & on this line
} else {
    s = &SessionB{}  // note & on this line
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can write a function that accept interface

package main

import "fmt"

type Session interface {
    StartSession()
}
type SessionA struct {
    jobs string
}

type SessionB struct {
    foods string
}

func (sessionA *SessionA) StartSession() {
    fmt.Printf("begin to do %s\n", sessionA.jobs)
}

func (sessionB *SessionB) StartSession() {
    fmt.Printf("begin to eat %s\n", sessionB.foods)
}

func main() {
    sessionType := 1 // maybe 2, just example
    sessionA:= &SessionA{
        jobs: "job1",
    }
    sessionB := &SessionB{
        foods: "food1",
    }


    if sessionType == 1 {
        runSession(sessionA)
    } else {
        runSession(sessionB)
    }
    
    
}

func runSession(s Session) {
    s.StartSession()
}

Comments

0

you can use an strategy pattern, with that appproach you are able to extend your code in case you need it. The object that is intanced on runtime depends on some context.

type Session interface { //the common behaviour
    StartSession()
}

type SessionA struct {
    jobs string
}

type SessionB struct {
    foods string
}

func (sessionA *SessionA) StartSession() {
    fmt.Printf("begin to do %s\n", sessionA.jobs)
}

func (sessionB *SessionB) StartSession() {
    fmt.Printf("begin to eat %s\n", sessionB.foods)
}

your main could be:

func main() {
    sessionToExcecute := 1
    sessions := map[int]Session{
        1: &SessionA{jobs: "some job"},
        2: &SessionB{foods: "a food"},
    }
    sessions[sessionToExcecute].StartSession()
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.