0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

戻り値がCreateAccountUseCase型指定なのにcreateAccountInteractor型を返しても良い理由

Last updated at Posted at 2025-03-04

問題のコード

func NewCreateAccountInteractor(
	repo domain.AccountRepository,
	presenter CreateAccountPresenter,
	t time.Duration,
) CreateAccountUseCase {
	return createAccountInteractor{
		repo:       repo,
		presenter:  presenter,
		ctxTimeout: t,
	}
}

フルのコード

ポイント1:インターフェースとは?

Goのインターフェースは「メソッドの集合」のこと。
つまり、特定のメソッドを持っていれば、その型はインターフェースを実装しているとみなされる

type CreateAccountUseCase interface {
    Execute(context.Context, CreateAccountInput) (CreateAccountOutput, error)
}
  • CreateAccountUseCaseExecute メソッドを持っているものを指す。
  • 明示的に implements とは書かない。

ポイント2:createAccountInteractorExecute を持っている

type createAccountInteractor struct {
    repo       domain.AccountRepository
    presenter  CreateAccountPresenter
    ctxTimeout time.Duration
}

func (a createAccountInteractor) Execute(ctx context.Context, input CreateAccountInput) (CreateAccountOutput, error) {
    // 実装
}
  • createAccountInteractor には Execute メソッドがある。
  • だから、Goの型システムが「この構造体は CreateAccountUseCase を満たしている」と認識する

func(a createAccountInteractor)...の文法については以下を参照


ポイント3:NewCreateAccountInteractor の戻り値

func NewCreateAccountInteractor(
    repo domain.AccountRepository,
    presenter CreateAccountPresenter,
    t time.Duration,
) CreateAccountUseCase {
    return createAccountInteractor{ // ここで構造体を返している
        repo:       repo,
        presenter:  presenter,
        ctxTimeout: t,
    }
}
  • CreateAccountUseCaseExecute を持つものならOK!
  • createAccountInteractorExecute を持っているのでOK!
  • だから、createAccountInteractor を返してもエラーにならない。

わかりやすい例

例1:シンプルなインターフェースと構造体

package main

import "fmt"

// インターフェース
type Speaker interface {
    Speak() string
}

// 構造体
type Person struct {
    Name string
}

// `Person` は `Speaker` を実装している
func (p Person) Speak() string {
    return "Hello, my name is " + p.Name
}

// `Speaker` を返す関数
func NewPerson(name string) Speaker {
    return Person{Name: name} // Personを返しているけどOK
}

func main() {
    var s Speaker = NewPerson("Alice")
    fmt.Println(s.Speak()) // "Hello, my name is Alice"
}
  • NewPersonSpeaker 型を返すと言っている。
  • PersonSpeak を持っているので、Goの型システムが「これは Speaker を満たしている」と判断。
  • だから PersonSpeaker として返してもOK!

例2:ポインタを使う場合

func NewPerson(name string) Speaker {
    return &Person{Name: name} // ポインタを返す
}
  • &Person{} にすると、ポインタを返すことになる。
  • Speaker にポインタが必要な場合はこうする。

結論

createAccountInteractorExecute を持っているから CreateAccountUseCase を満たす。
だから、CreateAccountUseCase を返す関数で createAccountInteractor を返しても問題ない!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?