英文:
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 = "a" | "b"
// can only be "a" or "b"
const myVar:NamedString = "a"
// throws err when trying to set for anything else:
const myVar:NamedString = "c" // <- Err: Type '"c"' is not assignable to type 'NamedString'.
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("不支持的值")
}
}
如果你不关心AString
和BString
的内容,只想区分它们,你可以使用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("a")
// val == Astring returs 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("unsupported value")
}
}
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 "a":
return AString, nil
case "b":
return BString, nil
default:
return 0, errors.New("unsupported value")
}
}
答案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 (
"fmt"
)
type NamedString string
const (
aNamed NamedString = "a"
bNamed NamedString = "b"
)
func returnString() string {
return ""
}
func main() {
myVar := aNamed
fmt.Println(myVar)
// Still works due to "d" being an untyped constant
myVar = "d"
fmt.Println(myVar)
// Error since "d" is of type string now and not a named string
myVar = string("d")
// Also error due to the method returning a string and not a named string
myVar = returnString()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论