Conversion between slices of the same underling types

229 views
Skip to first unread message

David DENG

unread,
Jun 25, 2015, 2:32:51 PM6/25/15
to golan...@googlegroups.com
(Not sure about whether this has been  proposed (and denied) or discussed somewhere else).

For example, we have

type INT int
var i []INT

the compiler can allow the following type conversion:

j := []int(i) 
// or allow this:
sort.Ints([]int(i))
 
If this has been discussed, can anybody show me the final reason not to allow it? Thanks.

Or, if anybody can show me an easy way of sorting a slice of int/float with element type a self-defined type. For "easy" I mean no need to define a type for the slice and then methods of sort.Interface. Copying the data to a []int/[]float64, sort, and copying back is not a good way for me.

Thanks!

Jan Mercl

unread,
Jun 25, 2015, 3:24:20 PM6/25/15
to golan...@googlegroups.com
On Thu, Jun 25, 2015 at 8:33 PM David DENG <david...@gmail.com> wrote:

Conversion between any types having the same underlying type is permitted by the specs[0]:

""""
A non-constant value x can be converted to type T in any of these cases:
...
x's type and T have identical underlying types.
...
""""

However, in the case you seem to be looking for, the underlying types are not the same.

If such conversions between [slice] types of different underlying types would be permitted then the conversion would have to convert and copy the slice elements one by one - in the general case, as there's no guarantee that the memory layout is compatible.


> For "easy" I mean no need to define a type for the slice and then methods of sort.Interface.

That's often only a handful of SLOCs. Seems easy to me.


--

-j

David DENG

unread,
Jun 25, 2015, 3:59:59 PM6/25/15
to golan...@googlegroups.com
Thanks!

I know it doesn't compile and how the spec doesn't allow this.

So I'm just suggesting conversions between slice of the SAME underlying types, in which case no need to copy the elements one by one because the memory layout is compatible.

This is quite different from assigning a []int to a []interface{}.
Quite verbose to me. I've heard quite a few complaining from my friends about writing verbose code in Go and some of them decided to give up learning of Go.

sara...@gmail.com

unread,
Jun 25, 2015, 4:41:37 PM6/25/15
to golan...@googlegroups.com
You could add a sort method to the new type so then all you do is call sort on it. That's one way I've seen others solve this.

type INT int
type INTS []INT
var i INTS

func (s INTS) Sort() {
    //sort code here
}

What kind of type declarations are they creating? Do you have an example they ran into other than the one you provided?

David DENG

unread,
Jun 25, 2015, 5:28:38 PM6/25/15
to golan...@googlegroups.com, sara...@gmail.com
Defining the INTS implementing sort.Interface, I can simply call sort.Sort to sort the slice. Even if this sorting is just a one-time and small part of the job, I have to implement a new type.

Sometimes, they create new types just for calling a function with an interface as the input. Sort is a typical example. Another complaining about verbose code is related to error...and that is another story though (I'm quite ok with error).

sara...@gmail.com

unread,
Jun 25, 2015, 5:46:04 PM6/25/15
to golan...@googlegroups.com, sara...@gmail.com
I'm not sure I can help you then. Maybe someone with more go experience can help? 

Can you provide a more meaningful example than the []INT. Implementing sort.Interface is very simple in this case and it allows you to now sort. In more complicated cases, implementing the interface allows you to sort the type you created and isn't much work compared to the rest of your implementation.

I'm not sure I understand what you mean when you say, "Sometimes, they create new types just for calling a function with an interface as the input." 

sa...@scaledinference.com

unread,
Jun 27, 2015, 3:44:26 PM6/27/15
to golan...@googlegroups.com
so, if you really want to break the type system:

```
func uglyCast(s []Int) []int {
return *(*[]int)(unsafe.Pointer(&s))
}
```
http://play.golang.org/p/K2ip_UQbS0

Danver Braganza

unread,
Jun 27, 2015, 3:55:24 PM6/27/15
to golan...@googlegroups.com
I think the essential reason this isn't allowed is because you could be doing something like this:

type distanceFeet int
type distanceMetres int

myFeet := []distanceFeet{0, 0}

func SteerInMetres(instructions []distanceMetres) {//left out}

If SteerInMetres allowed you to accept anything that was an underlying []int, you could call it with your []distanceFeet, and then you lose your planetary lander.

In your case, you could implement a ToIntSlice() and FromIntSlice() method, so you can go ahead and sort, or implement Sortable, to get what you need.

David DENG

unread,
Jun 29, 2015, 11:58:30 AM6/29/15
to golan...@googlegroups.com
Using unsafe highly depends on the underlying implementation of the compiler. It'll be much more elegant if it is done by the compiler.

David DENG

unread,
Jun 29, 2015, 12:01:01 PM6/29/15
to golan...@googlegroups.com
Thanks for the reply but it doesn't persuade me because we can do the convertion when the variables are not slices but only the element types.

I was not suggesting directy assignment but allowing the explicit type converstion.
Reply all
Reply to author
Forward
0 new messages