[小ネタ] Go で struct から interface を抜き出すための interfaces

2021.07.07

概要

https://github.com/rjeczalik/interfaces を使えば struct から interface を抜き出すことができます。

背景

Go で struct で提供されているが interface は用意されていないことは多々あります。

使う側が interface を用意するのが一般的だからなのですが、

実際 interface を用意し、メンテし続けるのは面倒だと感じています。

機械的に interface ぐらい抜けるだろう、と思って探して見つかったのが

https://github.com/rjeczalik/interfaces でした。

やってみた

Install

go get -v github.com/rjeczalik/interfaces/cmd/interfacer

Usage

例えば、 dynamodb.Client を参照します。

interfacer -for "github.com/aws/aws-sdk-go-v2/service/dynamodb.Client" -as dynamodbapi.API

すると、下記のような interface を作成します。

// Code generated by interfacer; DO NOT EDIT

package dynamodbapi

import (
    "context"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
)

// API is an interface generated for "github.com/aws/aws-sdk-go-v2/service/dynamodb.Client".
type API interface {
    BatchExecuteStatement(context.Context, *dynamodb.BatchExecuteStatementInput, ...func(*dynamodb.Options)) (*dynamodb.BatchExecuteStatementOutput, error)
    BatchGetItem(context.Context, *dynamodb.BatchGetItemInput, ...func(*dynamodb.Options)) (*dynamodb.BatchGetItemOutput, error)
    BatchWriteItem(context.Context, *dynamodb.BatchWriteItemInput, ...func(*dynamodb.Options)) (*dynamodb.BatchWriteItemOutput, error)
    // ...
}

削って使用するメソッドだけに絞り込んでもよし、v1 のときのような iface として扱うのも良いです。

interface 化することで https://github.com/golang/mock でテストしやすくなります。

まとめ

struct から interface を抜き出すことをツールを使って行いました。

go の構文自体は簡潔でわかりやすいですが、その分、コードの量が多くなることがあります。

ツール使ったコード自動生成に嫌な思い出がある人も少なくはないとは思いますが、go での開発の際は採用の検討も視野にいれても良いのではないかと思います。