Question about "interface{}" convert to "string"

6,433 views
Skip to first unread message

Andreas Otto

unread,
Nov 23, 2010, 7:39:28 AM11/23/10
to golang-nuts
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi everybody,

one question about converting something to a "string"

Problem:

The pair "panic" and "recover" give you the possibility to
"throw" an arbitrary object as error.

example: panic("my error")

"recover" returns an "interface{}" or nil. ...

my problem is that the only way to convert an "interface{}",
using a "unknown" type, into an "string" is (as I know)

fmt.Sprintf("%s", ifc)

Is this right, or can I test for an "string" like interface?

what is the standard in GO if something support a serialization into a
"string" object

I already know the "os.Error" Interface, which require a "String" method.

mfg, Andreas Otto
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.15 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJM67YAAAoJEGTcPijNG3/ADaUIAIQ4E+RtVqBANtUbfHQTE5TI
8FhqxIfsJkQSZUO4uCBRczM3Fp/CL9j74AA3CL1Rb9HTX8ThdCZ6kwushrQ+zOAL
qo5psfZKJYqDlSPOJQ1V/nWROihgVuIGLbxgGCUAEFPXhHHvQShPH7Q8leOUIYpc
ml+Pl3gPrHApbx+TGa8tv2xI4ATolxRw987Qcs9XBdK97iQcdTgCAz13d7E4+d67
21XcjfYkC2DnbjIu+c0pm2iqnu3540CyXDRAcy0Zi/jcRL82GL1A1rdroP2YjlTc
Qkz2nr/TRX200idVW5xDfEq880obkMmM4xjh0g7SSRU8ESnkdZ2NPOG4kqFOQbE=
=Gucw
-----END PGP SIGNATURE-----

roger peppe

unread,
Nov 23, 2010, 7:50:59 AM11/23/10
to Andreas Otto, golang-nuts
On 23 November 2010 12:39, Andreas Otto <aott...@t-online.de> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi everybody,
>
> one question about converting something to a "string"
>
> Problem:
>
> The pair "panic" and "recover" give you the possibility to
> "throw" an arbitrary object as error.
>
> example: panic("my error")
>
> "recover" returns an "interface{}" or nil. ...
>
> my problem is that the only way to convert an "interface{}",
> using a "unknown" type, into an "string" is (as I know)
>
> fmt.Sprintf("%s", ifc)
>
> Is this right, or can I test for an "string" like interface?
>
> what is the standard in GO if something support a serialization into a
> "string" object
>
> I already know the "os.Error" Interface, which require a "String" method.

that's exactly it.

it's conventional to panic with an object that has a String method;
then you can do:

defer func() {
switch x := recover().type {
case os.Error:
log.Printf("panic with error %s", x.String())
case nil:
...
...

chris dollin

unread,
Nov 23, 2010, 7:55:32 AM11/23/10
to Andreas Otto, golang-nuts
On 23 November 2010 12:39, Andreas Otto <aott...@t-online.de> wrote:

> my problem is that the only way to convert an "interface{}",
> using a "unknown" type, into an "string" is (as I know)
>
> fmt.Sprintf("%s", ifc)
>
> Is this right, or can I test for an "string" like interface?

You can use a type test. If X is your interface{} variable and T is
the type you want to test for -- be it an interface type or a concrete
type -- then

aT, isT := X.(T)

will set isT to true iff X has underlying type T and aT to the corresponding
T value (the zero value if isT = false).

> what is the standard in GO if something support a serialization into a
> "string" object

fmt.Stringer looks like the plausible candidate.

Are you really sure you want to be doing this test? (You can test an
interface{} for equality against a string anyway ..)

Chris

--
Chris "allusive" Dollin

Andy Balholm

unread,
Jan 30, 2013, 11:08:37 AM1/30/13
to golan...@googlegroups.com, Andreas Otto, ehog....@googlemail.com
Chris's answer is correct, but a little out of date. Now error objects have an Error method instead of a String method. But it still returns a string. Do a type assertion to the new error interface.

On Tuesday, January 29, 2013 5:19:40 PM UTC-8, david wrote:
hi,friend!
can you relove this problem?I have encountered this problem.

bryanturley

unread,
Jan 30, 2013, 11:23:07 AM1/30/13
to golan...@googlegroups.com, Andreas Otto, ehog....@googlemail.com
Might be simpler to just return an error instead of panic()'ing.
Normally less interface {} involved in that.

Carlos Castillo

unread,
Feb 1, 2013, 11:25:14 AM2/1/13
to golan...@googlegroups.com, Andreas Otto, ehog....@googlemail.com
If you want the least amount of work, then use (similar to what OP suggests), fmt.Sprint(x), the downside is that it is does far more work as it makes a new string each time. The upside is that it should handle most types (including numeric types). Alternatively, if the only thing you are going to do is hand it to a fmt.* or log.* function, you could just leave it as an interface{} and let the function you call "stringify" it for you: http://play.golang.org/p/Ygq9nD75PF

Otherwise, if maximizing speed or minimizing string creation is important than you can use type switches / type assertions and / or reflect. Here I've created a toString method which, if possible, uses a method / feature of the type to avoid the extra work and the extra string conversion that fmt.SPrint* functions have to do. http://play.golang.org/p/fHs2ABo1c0

Also, there's an additional advantage that I can write custom string representations for types I don't have the ability to modify (see time.Time example).


On Tuesday, January 29, 2013 5:19:40 PM UTC-8, david wrote:
hi,friend!
can you relove this problem?I have encountered this problem.

On Tuesday, November 23, 2010 8:55:32 PM UTC+8, chris dollin wrote:

Carlos Castillo

unread,
Feb 1, 2013, 11:33:15 AM2/1/13
to golan...@googlegroups.com
That first sentence is a little confusing here's a (hopefully clearer) rewrite:

For the least amount of programmer work, you can use fmt.Sprint(x) to convert anything to a string the same way that fmt.* functions do. This is slightly less efficient than some other solutions, since the fmt.* functions were made to handle concatenation efficiently, and thus do their work on []byte slices, which requires extra conversion steps and results in new strings being made.
Reply all
Reply to author
Forward
0 new messages