いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-706 (インターフェースでジェネリックメソッドは宣言できない)(go1.27)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ · GitHub

概要

以下、自分用のメモです。

先日、Go 1.27で追加されるジェネリックメソッドについてメモ書きました。

devlights.hatenablog.com

書き忘れていたのですが、Go 1.27のジェネリックメソッドでは、以下の制限があります。

  • インターフェースのメソッド宣言に型パラメータは書けない
  • ジェネリックメソッドはインターフェースを実装できない

他の言語と同じ感覚で書いていると、コンパイルエラーになるので注意ですね。

試してみる

Goのバージョンは以下とします。

go version go1.27rc3 linux/amd64

ジェネリックメソッドを持つインターフェースをコンパイルしようとするとエラーになります。

package main

type (
    Stream[T any] interface {
        Map[U any](fn func(T) U) Stream[U]
    }
)

func main(){}
$ go1.27rc3 build
# app
./main.go:5:6: interface method must have no type parameters
./main.go:5:25: undefined: U

ちゃんとエラーになりますね。

構造体は大丈夫。コードに意味はないです。

package main

import (
    "fmt"
    "slices"
    "strconv"
)

type (
    Stream[T any] struct {
        items []T
    }
)

func New[T any]() *Stream[T] {
    s := make([]T, 0)
    return &Stream[T]{items: s}
}

func (me *Stream[T]) Add(v T) {
    me.items = append(me.items, v)
}

// ジェネリックメソッド
func (me *Stream[T]) Map[U any](fn func(T) U) *Stream[U] {
    r := make([]U, 0, len(me.items))

    for v := range slices.Values(me.items) {
        r = append(r, fn(v))
    }

    return &Stream[U]{items: r}
}

func main() {
    s1 := New[int]()

    for v := range 10 {
        s1.Add(v)
    }

    s2 := s1.Map[string](func(v int) string {
        return strconv.Itoa(v)
    })

    fmt.Println(s1.items)
    fmt.Println(s2.items)
}
$ go1.27rc3 run .
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]

参考情報

個人的Goのおすすめ書籍

個人的に読んでとても勉強になった書籍さんたちです。


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。