Extension for type assertion of interface array

217 views
Skip to first unread message

nsak...@gmail.com

unread,
Apr 18, 2018, 10:13:59 AM4/18/18
to golang-nuts
Go supports below type assertion

t := i.(T)
and 
t, ok := i.(T)

Can this feature be extended to array of interfaces as mentioned below?

t := i.([]T)
and 
t, ok := i.([]T)


I have been using Golang for almost four years and I have come across use cases requiring this feature many times. So far, I write a function for each specific case which clones the array into new array with type asserted to new type. I repeat the same pattern of assertion for array of different types and perform extra array copy each time I assert. Is there a better alternative solution with existing Go feature or Is there a chance that this feature will be supported in future?

Jan Mercl

unread,
Apr 18, 2018, 10:23:33 AM4/18/18
to nsak...@gmail.com, golang-nuts
On Wed, Apr 18, 2018 at 4:13 PM <nsak...@gmail.com> wrote:

When possible, avoid using '[]interface{}' and use just 'interface{}' instead: https://play.golang.org/p/oPtPoGChkMZ.


--

-j

Jan Mercl

unread,
Apr 18, 2018, 10:24:17 AM4/18/18
to nsak...@gmail.com, golang-nuts
On Wed, Apr 18, 2018 at 4:22 PM Jan Mercl <0xj...@gmail.com> wrote:
On Wed, Apr 18, 2018 at 4:13 PM <nsak...@gmail.com> wrote:

When possible, avoid using '[]interface{}' and use just 'interface{}' instead: https://play.golang.org/p/oPtPoGChkMZ.



The link should have been: https://play.golang.org/p/aLKIxkr3VKg
 

 
--

-j

--

-j

matthe...@gmail.com

unread,
Apr 18, 2018, 10:59:27 AM4/18/18
to golang-nuts
I think if you opened a proposal it would be merged into the generics discussion: https://github.com/golang/go/issues/15292

There may be other ways to write the program, can you provide a concrete example of where you’ve needed this?

Matt

nsak...@gmail.com

unread,
Apr 19, 2018, 12:59:12 AM4/19/18
to golang-nuts
Usescases that I came across doesn't involve []interface{}. 

My usecases will be similar to this sample code

type landSpace struct {
//consider that landSpace implements all functions from both Shape and property interfaces
...
}
type
Shape interface {
...
}


type property
interface {

...
}


var a []*landSpace

func processShapes(shapes []Shape) {
//....
}

func evaluateProperties(properties []Property) {
//....
}



If I want to pass the variable 'a' to both the functions, then I have to write two functions to clone and typeAssert to respective interfaces.

ankit...@redbus.com

unread,
Apr 19, 2018, 11:41:19 AM4/19/18
to golang-nuts
Though the above is not allowed, you can restructure your code to wrap your struct as array in another struct and have area() paas a index to the underlying struct. Something like this (landSpaceArr wraps landSpace struct) - 

type landSpace struct{
        side int
}

type landSpaceArr struct {
        lS []landSpace
}

func (s *landSpaceArr) area(i int) int {
        return s.lS[i].side * s.lS[i].side
}

type Shapes interface {
        area(int) int
}

func main() {

        v := make([]landSpace, 1)
        v[0].side =50
        a := &landSpaceArr{lS: v}

        processShapes(a, 0)
}

func processShapes(shapes Shapes, i int) {

        println(shapes.area(i))
}

~                                

::DISCLAIMER::
----------------------------------------------------------------------------------------------------------------------------------------------------

The contents of this e-mail and any attachments are confidential and intended for the named recipient(s) only.E-mail transmission is not guaranteed to be secure or error-free as information could be intercepted, corrupted,lost, destroyed, arrive late or incomplete, or may contain viruses in transmission. The e mail and its contents(with or without referred errors) shall therefore not attach any liability on the originator or redBus.com. Views or opinions, if any, presented in this email are solely those of the author and may not necessarily reflect the views or opinions of redBus.com. Any form of reproduction, dissemination, copying, disclosure, modification,distribution and / or publication of this message without the prior written consent of authorized representative of redbus.com is strictly prohibited. If you have received this email in error please delete it and notify the sender immediately.Before opening any email and/or attachments, please check them for viruses and other defects.

::DISCLAIMER::
----------------------------------------------------------------------------------------------------------------------------------------------------

The contents of this e-mail and any attachments are confidential and intended for the named recipient(s) only.E-mail transmission is not guaranteed to be secure or error-free as information could be intercepted, corrupted,lost, destroyed, arrive late or incomplete, or may contain viruses in transmission. The e mail and its contents(with or without referred errors) shall therefore not attach any liability on the originator or redBus.com. Views or opinions, if any, presented in this email are solely those of the author and may not necessarily reflect the views or opinions of redBus.com. Any form of reproduction, dissemination, copying, disclosure, modification,distribution and / or publication of this message without the prior written consent of authorized representative of redbus.com is strictly prohibited. If you have received this email in error please delete it and notify the sender immediately.Before opening any email and/or attachments, please check them for viruses and other defects.

jake...@gmail.com

unread,
Apr 19, 2018, 12:06:38 PM4/19/18
to golang-nuts
Yes, to use the functions above you will need to copy the slices of landSpaceto slices of the respective interface types. But I you do not need to do any type assertions. Like this:

https://play.golang.org/p/eFTUqpImyPc
package main

import (
   
"fmt"
)

type landSpace
struct{}

func
(*landSpace) Foo() {
    fmt
.Println("Foo")
}

func
(*landSpace) Bar() {
    fmt
.Println("Bar")
}

type
Shape interface {
   
Foo()
}

type
Property interface {
   
Bar()

}

var a []*landSpace

func processShapes
(shapes []Shape) {

   
for _, s := range shapes {
        s
.Foo()
   
}
}

func evaluateProperties
(properties []Property) {
   
for _, p := range properties {
        p
.Bar()
   
}
}

func main
() {
    a
= append(a, &landSpace{}, &landSpace{})

   
var shapes []Shape
   
for _, l := range a {
        shapes
= append(shapes, l)
   
}
    processShapes
(shapes)

   
var properties []Property
   
for _, l := range a {
        properties
= append(properties, l)
   
}
    evaluateProperties
(properties)
    fmt
.Println("Hello, playground")
}

Is this what you meant? I see how something like shapes = a.([]Shape) would be convenient to avoid having to do an explicit conversion. Hoever, until Go has some form of generics,  it seems unlikely. Keep in mind that a Shape and *landSpace are two different types, with different in memory representations. So to avoid major language changes, the type assertion would have to create a new slice anyway.

nsak...@gmail.com

unread,
Apr 23, 2018, 12:48:33 AM4/23/18
to golang-nuts

Type assertion is not required in the given example (from array of structs to interface), But you need to assert if array of one interface is type casted to array of another interface. I started this thread to know whether this pattern requires a language level change to avoid unwanted array copy and code duplication for similar pattern of code. I agree that there are many ways in Golang to make this code run but shouldn't the language provide an extension to already available syntax to address this in simple and elegant way?

Alex Efros

unread,
Apr 26, 2018, 6:20:07 AM4/26/18
to golang-nuts
Hi!

On Sun, Apr 22, 2018 at 09:48:13PM -0700, nsak...@gmail.com wrote:
> this pattern requires a language level change to avoid unwanted array copy
[...]
> but shouldn't the language provide an extension to already available syntax

The language is trying to avoid hiding performance-critical things (like
copying an array) by nice syntax. You're supposed to always write such
code (like copy an array) manually, to make it clear what's happens.

To be clear, I'm not arguing this is good idea… but AFAIK it's official
position about such ideas… and it makes some sense.

--
WBR, Alex.

simon place

unread,
Apr 26, 2018, 12:38:50 PM4/26/18
to golang-nuts
i too didn't like this, although i get the reasons for it.

but for me these are unaddressed points;

1. the language does not distinguish array types, as a group, in any way, except here.
2. you can have many types that simultaneously implement multiple interfaces, for these you need copying code for every COMBINATION.
3. interfaces are commonly used by libraries, library users providing the implementations, this makes its impossible to provide the copying in the library, and makes the use of arrays of interfaces much less friendly.

it does seem like some generics should improve this situation.
Reply all
Reply to author
Forward
0 new messages