Преобразование типов в аналогичный тип

Я пытаюсь повторно использовать пару кода (ключ / значение) для создания типов ec2.Tag и autoscaling.Tag, которые также являются парами ключ / значение. Но я не думаю, что знаю достаточно о конверсии / кастинге, пожалуйста, посоветуйте. Заранее спасибо.

panic: преобразование интерфейса: interface {} is []struct { Key string; Строка значения}, а не []*ec2.Tag

func (c *CloudWorks) GetTagCollection() interface{} {

    return []struct {
        Key   string
        Value string
    }{
     {
        Key:   "key-a",
        Value: "value-a",
    },
    {
        Key:   "key-b",
        Value: "value-b",
    },
    {
        Key:   "key-c",
        Value: "value-c",
    },
    }

}

func (c *CloudWorks) GetTags() []*ec2.Tag {

    //return []*autoscaling.Tag{

    // WORKS
    //return []*ec2.Tag{
    //  {
    //      Key:   aws.String("key1"),
    //      Value: aws.String("value1"),
    //  },
    //  {
    //      Key:   aws.String("key2"),
    //      Value: aws.String("value3"),
    //  },
    //  {
    //      Key:   aws.String("key3"),
    //      Value: aws.String("value3"),
    //  },
    //}

    // FAIL
    return c.GetTagCollection().([]*ec2.Tag)

}

РЕДАКТИРОВАТЬ Моя цель - избежать дублирования кода, как я могу повторно использовать пары ключ-значение в обеих функциях, большое спасибо.

func (c *CloudWorks) GetEC2Tags() []*ec2.Tag {

return []*ec2.Tag{
    {
        Key:   aws.String("key1"),
        Value: aws.String("value1"),
    },
    {
        Key:   aws.String("key2"),
        Value: aws.String("value3"),
    },
}

}

func (c *CloudWorks) GetAutoscalingTags() []*autoscaling.Tag {

return []*autoscaling.Tag{
    {
        Key:   aws.String("key1"),
        Value: aws.String("value1"),
    },
    {
        Key:   aws.String("key2"),
        Value: aws.String("value3"),
    },
}

}

1 ответ

Термин, который вы используете, не conversion/castingэто утверждение типа, которое используется для получения базового значения интерфейса. Поскольку интерфейс, который вы используете для переноса содержимого функции при возврате данных, является частью структуры. Вот причина ошибки:

panic: преобразование интерфейса: interface{} is []struct { Key string; Строка значения}, а не []*ec2.Tag

Тип утверждение неверно, потому что вы используете []*ec2.Tag тип объявления, который должен быть частью структуры []struct вернулся из функции c.GetTagCollection(), Поэтому вы должны набрать assert для этого типа как:

result := c.GetTagCollection().([]struct)

Утверждение типа, используемое в присваивании или инициализации специальной формы, поэтому вы проверяете, работает ли утверждение типа:

v, ok = x.(T)
v, ok := x.(T)

Для выражения x типа интерфейса и типа T основное выражение

x.(T)

утверждает, что x не равен nil и что значение, хранящееся в x, имеет тип T. Обозначение x. (T) называется утверждением типа.

Точнее, если T не является интерфейсным типом, x. (T) утверждает, что динамический тип x идентичен типу T. В этом случае T должен реализовать тип (interface) x; в противном случае утверждение типа является недопустимым, поскольку для x невозможно сохранить значение типа T. Если T является типом интерфейса, x. (T) утверждает, что динамический тип x реализует интерфейс T.

Примечание. Если утверждение типа выполнено, значением выражения является значение, хранящееся в x, а его тип - T. Если утверждение типа равно false, возникает паника во время выполнения.

Редактировать: Голанг строго о типах. Таким образом, вы не можете присвоить значение одного типа другому типу, пока не преобразуете значение в другой тип. AWS создает свои собственные типы, используя предоставленную строку. Возьмем для примера:

package main

import (
    "fmt"
)

type MyInt int 

func main() {
    var x int
    x = 1
    var y MyInt
    y = 1
    fmt.Println(x==y)
}

Выше кода будет выдавать ошибку несоответствия типов

prog.go:14:18: недопустимая операция: x == y (несовпадающие типы int и MyInt)

Рабочий код на детской площадке

Другие вопросы по тегам