If I have a type defined as a string constant, why can't I pass that type to functions as an actual string?

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

If I have a type defined as a string constant, why can't I pass that type to functions as an actual string?

问题

这是我的意思:Go playground

"StringType" 类型是一个字符串,没有其他特殊之处。编译器在第21行报错,但是奇怪的是,如果你注释掉第21行并取消注释第22行,第16行却可以正常工作。

这两行代码有什么区别(因为它们都将 StringType 传递给同一个函数),为什么其中一行可以工作而另一行不行?

以下是代码:

package main

import (
	"fmt"
	"strings"
)

type StringType string

const (
	FirstString  = "first"
	SecondString = "second"
)

func main() {
	fmt.Println(strings.Contains(FirstString, SecondString))    // 第16行
}

func myFunc(a StringType, b StringType) bool {
	return strings.Contains(a, b)                               // 第21行
	//return false
}
英文:

Here's what I mean: Go playground

The "StringType" type is a string and nothing more. The compiler complains about line 21, but for some reason, line 16 works without issue (if you comment 21 and uncomment 22).

What is the difference between those two lines (as both as passing StringType to the same function), and why does one work and the other not?

Here's the code, in-line:

package main

import (
    "fmt"
    "strings"
)

type StringType string

const (
	FirstString  = "first"
	SecondString = "second"
)

func main() {
	fmt.Println(strings.Contains(FirstString, SecondString))    // line 16
}

func myFunc(a StringType, b StringType) bool {

	return strings.Contains(a, b)                               // line 21
	//return false
}

答案1

得分: 3

Go有严格的类型系统。StringTypestring不是相同的类型,你需要进行类型转换。

Go规范中指出:

>非常量值x可以在以下任何情况下转换为类型T:
>
x可以赋值给T。
x的类型和T具有相同的基础类型。
...
x是一个可以用T类型的值表示的无类型常量。

由于StringType具有string的基础类型,可以进行如下转换:

func myFunc(a StringType, b StringType) bool {

    return strings.Contains(string(a), string(b))
    //return false
}

此外,由于FirstStringSecondString是可以用StringType表示的无类型常量,根据规范,你可以将它们作为StringType传递。

英文:

Go has a strict typing system. StringType and string is not the same type, and you need to do a type conversion.

The Go specs states that:

>A non-constant value x can be converted to type T in any of these cases:
>
x is assignable to T.
x's type and T have identical underlying types.
...
x is an untyped constant representable by a value of type T

Since StringType has the underlying type of string, this conversion is possible:

func myFunc(a StringType, b StringType) bool {

    return strings.Contains(string(a), string(b))
    //return false
}

Also, because FirstString and SecondString are untyped constants representable by StringType, this will allow you to pass it as a StringType, as stated by the specs.

答案2

得分: 0

在第一个情况下,你传递的是字符串,没有问题。

在第二个情况下,你传递的是StringType的值,而不是字符串。你需要告诉编译器它们是字符串,通过进行转换:

return strings.Contains(a, b)

替换为

return strings.Contains(string(a), string(b))
英文:

In the first case, you're passing strings, no problem.

In the second one, you pass StringType values instead of strings. You need to tell the compiler they're strings by converting them :

Replace

return strings.Contains(a, b)

with

return strings.Contains(string(a), string(b))

答案3

得分: 0

因为StringType不是string类型,所以不能将其赋值给string类型的变量。Go是一种强类型语言。但是由于StringTypestring的底层类型相同,你可以使用转换

return strings.Contains(string(a), string(b))
英文:

Because StringType is not of type string it cannot be assigned to anything of type string. Go is a strongly typed language. But as the underlying types of StringType and string are the same, you can use a conversion:

return strings.Contains(string(a), string(b))

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

发表评论

匿名网友

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

确定