5

我想regexp从 Go 标准库扩展,以便能够定义我自己的方法。我使用以下结构:

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.Regexp为我的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 回答