3 回答
TA贡献1828条经验 获得超3个赞
一个合乎逻辑的解决方案是使用*stringAinar-G 提到的。另一个答案详细说明了获取指向值的指针的可能性(int64但同样适用string)。包装器是另一种解决方案。
仅使用 string
可选string表示string加 1 的特定值(或状态)表示“不是字符串”(而是 a null)。
这1个特定值可以存储(信号)在另一个变量(例如bool),你可以包装string和bool成struct和我们到达的包装,但这并不适合进入的情况下,“只用string”(但仍然是一个可行的解决方案)。
如果我们只想坚持 a string,我们可以从string类型的可能值中取出 1 个特定值(它具有“无穷大”可能值,因为长度不受限制(或者可能是因为它必须是 anint但仅此而已)对)),我们可以将这个特定的值命名为null值,该值的意思是“不是字符串”。
最方便的指示值null是 的零值string,即空string: ""。指定这个null元素很方便,每当你创建一个string没有明确指定初始值的变量时,它都会被初始化""。还从一个查询的元素时map,其值是string也将产生""如果键不在map。
该解决方案适合许多现实生活中的用例。string例如,如果可选项应该是一个人的名字,那么空string并不意味着一个有效的人名,所以你首先不应该允许它。
当然,可能存在空string值确实表示string类型变量的有效值的情况。对于这些用例,我们可以选择另一个值。
在 Go 中, astring实际上是一个只读的字节片。请参阅博客文章Go 中的字符串、字节、符文和字符,其中详细解释了这一点。
所以 astring是一个字节切片,它是有效文本情况下的 UTF-8 编码字节。假设你想在你的可选中存储一个有效的文本string(如果你不想,那么你可以使用一个[]byte可以有一个nil值的代替),你可以选择一个string代表无效 UTF-8 字节序列的值,因此你赢了甚至不必妥协以从可能的值中排除有效文本。例如,最短的无效 UTF-8 字节序列仅为 1 个字节0xff(还有更多)。注意:您可以使用该utf8.ValidString()函数来判断一个string值是否为有效文本(有效的 UTF-8 编码字节序列)。
您可以将此特殊值设为 a const:
const Null = "\xff"
这么短也意味着检查 a 是否string等于 this会非常快。
按照这个约定,你已经有了一个可选的string,它也允许空的string.
在Go Playground上试一试。
const Null = "\xff"
func main() {
fmt.Println(utf8.ValidString(Null)) // false
s := Null
fmt.Println([]byte(s)) // [255]
fmt.Println(s == Null) // true
s = "notnull"
fmt.Println(s == Null) // false
}
TA贡献1784条经验 获得超9个赞
你可以使用类似的东西sql.NullString,但我个人会坚持使用*string. 至于尴尬,确实不能只是sp := &"foo"不幸。但是有一个解决方法:
func strPtr(s string) *string {
return &s
}
调用strPtr("foo")应该被内联,所以它是有效的&"foo"。
另一种可能性是使用new:
sp := new(string)
*sp = "foo"
TA贡献1866条经验 获得超5个赞
对于接口类型,您可以使用更自然的赋值语法。
var myString interface{} // used as type <string>
myString = nil // nil is the default -- and indicates 'empty'
myString = "a value"
在引用值时,通常需要类型断言来明确检查。
// checked type assertion
if s, exists := myString.(string); exists {
useString(s)
}
此外,由于stringers,在某些上下文中将自动处理“可选”类型——这意味着您不需要显式转换该值。该fmt软件包使用此功能:
fmt.Println("myString:",myString) // prints the value (or "<nil>")
警告
分配给值时没有类型检查。
在某些方面,这是一种比处理指针更简洁的方法。但是,因为这使用了接口类型,所以它不限于持有特定的底层类型。风险在于您可能会无意中分配不同的类型——这将nil与上述条件中的处理方式相同。
下面是使用接口进行赋值的演示:
var a interface{} = "hello"
var b = a // b is an interface too
b = 123 // assign a different type
fmt.Printf("a: (%T) %v\n", a, a)
fmt.Printf("b: (%T) %v\n", b, b)
输出:
a:(字符串)你好
b: (int) 123
请注意,接口是通过重复分配的,因此a和b是不同的。
- 3 回答
- 0 关注
- 194 浏览
添加回答
举报