如何创建一个字符串,它可以是两个值中的一个。

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

How to create a string that is one of either values

问题

我想声明一个变量,它的值只能是其中之一,在Typescript中的写法如下:

type NamedString string

const (
    A NamedString = "a"
    B NamedString = "b"
)

// 只能是 "a" 或 "b"
var myVar NamedString = A

// 当尝试设置其他值时会报错:
var myVar NamedString = "c" // <- 报错:cannot use "c" (type string) as type NamedString in assignment.

在Go语言中,你可以使用自定义类型和常量来实现相同的功能。

英文:

I would like to declare a variable that is one of either values, which in Typescript would look like:



type NamedString = &quot;a&quot; | &quot;b&quot;

// can only be &quot;a&quot; or &quot;b&quot;
const myVar:NamedString = &quot;a&quot;

// throws err when trying to set for anything else:
const myVar:NamedString = &quot;c&quot; // &lt;- Err: Type &#39;&quot;c&quot;&#39; is not assignable to type &#39;NamedString&#39;.

How would I go about achieving the same functionality in Go?

答案1

得分: 3

我会这样处理,因为你不能真正限制变量的内容:

type NamedString string

// 用于相等性检查的常量。
// 例如:
// val, err := NamedStringByValue("a")
// val == Astring 返回 true
const (
   Astring NamedString = "a"
   Bstring = "b"
)

func NamedStringByValue(val string) (NamedString, error) {
    switch val {
    case "a", "b":
        return NamedString(val), nil
    default:
        return "", errors.New("不支持的值")
    }
}

如果你不关心AStringBString的内容,只想区分它们,你可以使用iota,像这样:

type NamedString int

// 加1,这样在出现错误时可以返回默认值(对于int来说是0)。
const (
    AString NamedString = iota + 1
    BString
)

func NamedStringByValue(val string) (NamedString, error) {
    switch val {
    case "a":
        return AString, nil
    case "b":
        return BString, nil
    default:
        return 0, errors.New("不支持的值")
    }
}
英文:

I would approach it like that, since you can't really restrict the content of a variable:

type NamedString string

// Constants for equality check.
// E.x: 
// val, err := NamedStringByValue(&quot;a&quot;)
// val == Astring returs true
const (
   Astring NamedString = &quot;a&quot;
   Bstring = &quot;b&quot;
)

func NamedStringByValue(val string) (NamedString, error) {
    switch val {
    case &quot;a&quot;, &quot;b&quot;:
        return NamedString(val), nil
    default:
        return &quot;&quot;, errors.New(&quot;unsupported value&quot;)
    }
}

If you don't care about the content of the AString and BString and you just wanna distinguish them, you could make use of iota like that:

type NamedString int

// Plus 1, so that default value (0 for ints) can be returned
// in case of an error.
const (
    AString NamedString = iota + 1
    BString
)

func NamedStringByValue(val string) (NamedString, error) {
    switch val {
    case &quot;a&quot;:
        return AString, nil
    case &quot;b&quot;:
        return BString, nil
    default:
        return 0, errors.New(&quot;unsupported value&quot;)
    }
}

答案2

得分: 1

这个功能在Go语言中还没有完全实现。

然而,你最好的选择是创建一个新类型,并使用类型常量来表示字符串可以取的值。

据我所知,你无法避免将无类型常量(如"c")赋值给你的字符串。

package main

import (
	"fmt"
)

type NamedString string 

const (
	aNamed NamedString = "a"
	bNamed NamedString = "b" 
)

func returnString() string {
	return ""
}

func main() {
	myVar := aNamed
	fmt.Println(myVar)
	
	// 由于"d"是无类型常量,所以仍然有效
	myVar = "d"
	fmt.Println(myVar)
	
	// 错误,因为"d"现在是字符串类型,而不是命名字符串类型
	myVar = string("d")
	
	// 由于该方法返回的是字符串而不是命名字符串,所以也会出错
	myVar = returnString()
}
英文:

This functionality isn't quite in Go

Your best bet however is making a new type and using typed constants for the values the string can take

You can't get around being able to assign an untyped constant (like "c") to your string as far as I know.

package main

import (
	&quot;fmt&quot;
)

type NamedString string 

const (
	aNamed NamedString = &quot;a&quot;
	bNamed NamedString = &quot;b&quot; 
)

func returnString() string {
	return &quot;&quot;
}

func main() {
	myVar := aNamed
	fmt.Println(myVar)
	
	// Still works due to &quot;d&quot; being an untyped constant
	myVar = &quot;d&quot;
	fmt.Println(myVar)
	
	// Error since &quot;d&quot; is of type string now and not a named string
	myVar = string(&quot;d&quot;)
	
	// Also error due to the method returning a string and not a named string
	myVar = returnString()
}

huangapple
  • 本文由 发表于 2022年4月12日 00:11:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/71831033.html
匿名

发表评论

匿名网友

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

确定