在Go中创建带有约束的自定义类型。

huangapple go评论75阅读模式
英文:

Create a custom type with constraint in Go

问题

在Go语言中,你可以使用自定义类型和方法来实现只接受有效值的类型。以下是一个示例代码,演示了如何创建一个名为"Names"的自定义类型,其基础类型为字符串,但只接受"John"、"Rob"或"Paul"这些值,其他值将返回错误。

package main

import (
	"errors"
	"fmt"
)

type Names string

const (
	John Names = "John"
	Rob  Names = "Rob"
	Paul Names = "Paul"
)

func (n Names) IsValid() bool {
	return n == John || n == Rob || n == Paul
}

func NewName(name string) (Names, error) {
	n := Names(name)
	if !n.IsValid() {
		return "", errors.New("Invalid name")
	}
	return n, nil
}

func main() {
	name, err := NewName("John")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Valid name:", name)
}

在这个示例中,我们定义了一个Names类型,它是一个字符串类型的别名。我们还定义了三个常量JohnRobPaul,它们是Names类型的有效值。

我们还为Names类型定义了一个IsValid方法,用于检查给定的值是否为有效值。在NewName函数中,我们使用该方法来验证传入的值是否有效。如果值有效,我们返回一个Names类型的实例,否则返回一个错误。

main函数中,我们使用NewName函数来创建一个名为"John"的Names类型的实例。如果创建成功,我们打印出有效的名字;否则,我们打印出错误信息。

你可以在这里查看并运行这个示例代码。

英文:

How do I create a custom type in Go where only valid values can be accepted?
For example, I want to create a type called "Names" where its underlying type is a string. However it can only accept the values "John", "Rob" or "Paul". Any other value will return an error.
I've create the following program in a very simplistic way just to represent what I would like to achieve.

http://play.golang.org/p/jzZwALsiXz

What would be the best way to write this code?

答案1

得分: 9

你可以这样做(http://play.golang.org/p/JaIr_0a5_-):

type Name struct {
    string
}

func (n *Name) String() string {
    return n.string
}

func NewName(name string) (*Name, error) {
    switch name {
    case "John":
    case "Paul":
    case "Rob":
    default:
        return nil, fmt.Errorf("Wrong value")
    }
    return &Name{string: name}, nil
}

Golang不提供运算符重载,所以你不能在转换或赋值时进行检查。

根据你想要做什么,你可能想要这样做(http://play.golang.org/p/uXtnHKNRxk):

type Name string

func (n Name) String() string {
    switch n {
    case "John":
    case "Paul":
    case "Rob":
    default:
        return "Error: Wrong value"
    }
    return string(n)
}
英文:

You could do something like this (http://play.golang.org/p/JaIr_0a5_-):

type Name struct {
	string
}

func (n *Name) String() string {
	return n.string
}

func NewName(name string) (*Name, error) {
	switch name {
	case "John":
	case "Paul":
	case "Rob":
	default:
		return nil, fmt.Errorf("Wrong value")
	}
	return &Name{string: name}, nil
}

Golang does not provide operator overload so you can't make the check while casting or affecting value.

Depending on what you are trying to do, you might want to do something like this (http://play.golang.org/p/uXtnHKNRxk):

type Name string

func (n Name) String() string {
	switch n {
	case "John":
	case "Paul":
	case "Rob":
	default:
		return "Error: Wrong value"
	}
	return string(n)
}

huangapple
  • 本文由 发表于 2013年9月25日 06:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/18992930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定