Home > Back-end >  string vs []byte type definition
string vs []byte type definition

Time:01-11

If I have this code, it works as expected:

package main
import "strconv"

type text []byte

func main() {
   hello := text("hello")
   _ = strconv.AppendQuote(hello, " world")
}

but this code fails:

package main
import "strconv"

type text string

func main() {
   hello := text("hello")
   // cannot use hello (type text) as type string in argument to strconv.Quote
   _ = strconv.Quote(hello)
}

Why does one pass and the other fail? I checked the docs [1], but I didnt see anything that explained the difference.

  1. https://go.dev/ref/spec#Type_definitions

CodePudding user response:

What you are looking for is under Assignability:

https://go.dev/ref/spec#Assignability

In particular:

x's type V and T have identical underlying types and at least one of V or T is not a defined type.

In both cases, the underlying types are equal ([]byte is required and text is passed in case 1, string is required and text is passed in case 2), but []byte is not a defined type and string is, so it works for the first case, but not the second.

CodePudding user response:

You need to piece together several definitions from the language specifications to understand what's going on:

First is Assignability:

x's type V and T have identical underlying types and at least one of V or T is not a defined type.

Then you need to examine your V and T.

In your first code snippet you have type text []byte (the V) and a function AppendQuote whose required argument is []byte (the T).

Do V and T have identical underlying types? Yes. text's underlying type is []byte by your definition, and []byte is a composite type, whose underlying type is itself. From Types:

Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself

and the paragraph just above that:

Composite types —[...] slice, [...] — may be constructed using type literals.

And, is at least one of V or T not a defined type? Yes, []byte as stated above is a composite type.

Hence a variable of type text is assignable to []byte, including passing arguments to a function.


In your second code snippet you have type text string (the V) and a function Quote whose required argument is string (the T).

Do V and T have identical underlying types? Yes. One by definition, and the other one is the predeclared type string (same quote as above).

Finally, is at least one of V or T not a defined type? No! Both are defined types. text is defined by you and string is defined by the language specs in String types:

The predeclared string type is string; it is a defined type.

So assigning text to string does not meet the conditions for assignability and it gives a compiler error.

CodePudding user response:

AppendQuote accept []byte as argurment and your hello is defined as text type which is a []byte from your type definition, that is why it works.

func strconv.AppendQuote(dst []byte, s string) []byte see source code

while Quote accepts string as argument,

func strconv.Quote(s string) string see source code

And your hello type is []byte, not string. that's why it didn't work. you will either have to use the first case, or change your hello into string. e.g. _ = strconv.Quote("hello") in order for it to work.

  •  Tags:  
  • Related