5

Go 標準ライブラリからを拡張してregexp、独自のメソッドを定義できるようにしたいと考えています。次の構造体を使用します。

type RichRegexp struct {
    *regexp.Regexp
}

ご覧のとおり、この構造体にはラップされregexp.Regexpた . したがって、これを次のような単純な型宣言に置き換えることができるかどうか疑問に思います。

type RichRegexp regexp.Regexp

しかし、次の関数はどのように記述すればよいでしょうか。

func Compile(expression string) (*RichRegexp, error) {
    regex, err := regexp.Compile(expression)
    if err != nil {
        return nil, err
    }
    return &RichRegexp{regex}, nil // How to do this?
}

regexp.Regexpmyに変換しようとしましRichRegexpたが、コンパイルできませんでした。基になる型をラップするカスタム型を返す一般的なパターンは何ですか?

4

2 に答える 2

5

変換を使用できますが、この場合、型定義がポインターではないことが必要です。

type MyRegexp *regexp.Regexp // Doesn't work

これは仕様に裏打ちされています:

受信側の型は、T または *T の形式である必要があります。ここで、T は型名です。T で示される型は、レシーバーの基本型と呼ばれます。ポインターまたはインターフェイス型であってはならず、メソッドと同じパッケージで宣言する必要があります。メソッドは基本型にバインドされていると言われ、メソッド名はその型のセレクター内でのみ表示されます。

ただし、これを行うことができます:

type MyRegexp regexp.Regexp

現在値を処理しているため、次のことができます。

x := regexp.MustCompile(".*")
y := MyRegexp(*x)

そして、独自の正規表現タイプがあります。

プレイ中の完全なコード: http://play.golang.org/p/OWNdA2FinN

一般的なパターンとして、私は言うでしょう:

  • 変更される可能性が低く、任意の値を格納する必要がない場合は、型変換を使用します。
  • 埋め込み型とともに値を格納する必要がある場合は、struct.
  • コードが変更される可能性が高く、さまざまなものをサポートする必要がある場合は、インターフェイスを定義し、埋め込みや型変換を使用しないでください。
于 2012-11-04T14:27:38.830 に答える
3
package main

import (
        "regexp"
)

type RichRegexp regexp.Regexp

func Compile(expression string) (*RichRegexp, error) {
        regex, err := regexp.Compile(expression)
        if err != nil {
                return nil, err
        }

        return (*RichRegexp)(regex), nil
}

func main() {
    Compile("foo")
}

また、こちら: http://play.golang.org/p/cgpi8z2CfF

于 2012-11-04T14:11:21.227 に答える