Skip to content

proposal: embed: remove import restriction #43217

Closed
@rsc

Description

@rsc

@mdempsky points out in #41191 (comment) that the late addition of string and []byte to the embedding proposal has some unfortunate side effects that we might want to make sure we are happy with.

There are three details of string and []byte embedding that are at least surprising. This issue is about two of them. See #43216 for the third. The two for this issue are as follows.

First, to make sure source files containing embedding directives are clearly identified (by an import), we require an import _ "embed" to write

//go:embed hello.txt
var msg string

even though there is no use of the embed package. This requires a special case in goimports. (This is noted in the proposal as accepted.)

Second, the late addition says “a plain string or []byte variable”, and I really did mean those words. Only those specific types are allowed, not []uint8 and not other user-defined aliases for those types.

I see two options here. One is to do nothing and leave things as they are. That's possible and is the "this issue gets declined" outcome. The other option I can see is to introduce new type aliases embed.String and embed.Bytes and require those to be used as the types, which is what this proposal issue is meant to discuss and decide whether to accept.

Specifically:

package embed

// A String is a string that can be initialized using a //go:embed directive.
// It is an alias so that embed.String can be used as a string without
// any explicit conversion. The only expected use of this type is in
// var declarations accompanied by //go:embed directives. Elsewhere,
// code should simply use string.
type String = string

// A Bytes is a []byte that can be initialized using a //go:embed directive.
// It is an alias so that embed.Bytes can be used as a []byte without
// any explicit conversion. The only expected use of this type is in
// var declarations accompanied by //go:embed directives. Elsewhere,
// code should simply use []byte.
type Bytes = []byte

Then instead of writing:

//go:embed hello.txt
var msg string

You have to write:

//go:embed hello.txt
var msg embed.String

That solves both of the issues: the import is now required without any special case in goimports, and there is no question about whether []uint8 or other user-defined alias is OK. Only embed.String and embed.Bytes are OK.

What do people think? (Thumbs up / thumbs down is fine.)

[One option that's not on the table is removing string and []byte embedding entirely. Many people asked for that during the pre-proposal discussions, and I think it is important to respect that process. We can fix problems, but I think it would be improper to drop the functionality completely.]

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions