New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: spec: remove string(int/rune) #3939

Open
robpike opened this Issue Aug 10, 2012 · 16 comments

Comments

Projects
None yet
@robpike
Copy link
Contributor

robpike commented Aug 10, 2012

The conversion of an integer to a string was put in very early to bootstrap formatted
printing, if I remember correctly. It's odd, though, and no longer necessary, if it ever
was. It also causes inconsistencies, since string(0xD800) cannot produce the UTF-8
encoding for that code point (by definition, surrogates are not legal in UTF-8) so must
produce something else. We chose the "\uFFFD" since that's the only reasonable
option, but that means:

1) the result isn't obvious
2) string(0xD800) and "\uD800" do different things: the former produces the
UTF-8 for U+FFFD while the latter is statically rejected.

I propose that, in some remote future, we eliminate this conversion from the language.
@adg

This comment has been minimized.

Copy link
Contributor

adg commented Jan 21, 2013

Comment 1:

I guess we're bound by the Go 1 compatibility promise to keep this until Go 2.
@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Jul 30, 2013

Comment 2:

Labels changed: added go2.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Dec 4, 2013

Comment 3:

Labels changed: added repo-main.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Mar 3, 2014

Comment 4:

Adding Release=None to all Priority=Someday bugs.

Labels changed: added release-none.

@robpike robpike self-assigned this Mar 3, 2014

@rsc rsc added this to the Unplanned milestone Apr 10, 2015

@robpike robpike removed their assignment Sep 21, 2015

@dolmen

This comment has been minimized.

Copy link

dolmen commented Dec 14, 2016

I've been beaten by this "feature" in production code today.
My code was equivalent to this (but of course not so obvious: type, const and cast were in 3 different packages, and the cast result was an argument to a function, so that made the bad use of the cast quite hidden):

   type XType int16
   const x XType = 0x0001
   var y = string(x)

I think that go vet should raise an alert at least for my case (conversion to string of a value of a named integer type).

@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Dec 15, 2016

It is valid code, so vet will not complain about it. Perhaps golint should, but not vet.

@rsc rsc changed the title spec: disallow string(int/rune) spec: remove string(int/rune) Jun 17, 2017

@rsc rsc changed the title spec: remove string(int/rune) proposal: spec: remove string(int/rune) Jun 17, 2017

@urandom

This comment has been minimized.

Copy link

urandom commented Oct 25, 2017

Would it be possible to make string(int), return the string representation of the int. More users will probably expect this behaviour:

a := 42
fmt.Print(string(a)) // "42"

EDIT: got it, bad idea

@dominikh

This comment has been minimized.

Copy link
Member

dominikh commented Oct 25, 2017

@urandom I would not expect an innocuously looking conversion to invoke an expensive number formatting routine. The solution to fixing a (supposedly) confusing construct isn't to replace it with another, equally confusing one.

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Oct 25, 2017

No, that is not possible. It will silently break existing programs in a subtle way, for no real reason. If you want to convert an int (or a float or a bool) to a string, use package strconv. In particular, using strconv allows you more control over the exact formatting.

@griesemer

This comment has been minimized.

Copy link
Contributor

griesemer commented Jun 27, 2018

Another argument in favor of abandoning this feature is that it behaves differently when shifts are involved. See #26096 .

Jay54520 added a commit to Jay54520/Learn-Algorithms-With-Go that referenced this issue Jul 3, 2018

012-打印1到最大的N位数: v4: feat: add PermutationNum
使用 strconv.Itoa(num) 而不是 string(num) 转换数字

在 golang/go#3939 提议移除 string(int/rune),因为它不能提供正确的 UTF-8 编码点
@kindlyfire

This comment has been minimized.

Copy link

kindlyfire commented Aug 12, 2018

I wonder how to achieve what string(int) does with strconv ?

Doing string(65) returns "A", but I can't find a function in strconv that does that.

@cznic

This comment has been minimized.

Copy link
Contributor

cznic commented Aug 12, 2018

@griesemer

This comment has been minimized.

Copy link
Contributor

griesemer commented Aug 13, 2018

string(int) is really quite a complex operation as it needs to know utf8 encoding. @robpike 's original comment in this issue explains the rationale for removing it. Now that we have the proper libraries (uniccode, utf8) we can write this code explicitly. See e.g. runeToString here: https://play.golang.org/p/ZnUF0Oc_dAG .

@magical

This comment has been minimized.

Copy link
Contributor

magical commented Sep 13, 2018

@griesemer You don't even have to use a library. This works: string([]rune{65}) https://play.golang.org/p/I6aX3c6fG71. Unless we're proposing removing string([]rune) as well.

@griesemer

This comment has been minimized.

Copy link
Contributor

griesemer commented Sep 13, 2018

@magical Good point! I don't know about removing string([]rune). String(int/rune) is particularly annoying because the argument may be shift operation which opens a can of worms (see #26096 and various related issues).

@mimoo

This comment has been minimized.

Copy link

mimoo commented Oct 26, 2018

Note that python allows you to do str(42) -> "42" so this might bring confusion also.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment