Тип преобразования в Голанг - PullRequest
0 голосов
/ 17 октября 2019

Я новичок на Голанге. Я создал несколько пользовательских типов и запутался в их различиях в поведении - я что-то упустил в моем понимании. Я искал несколько ссылок переполнения стека, таких как Golang: преобразование типов - преобразование строки map [string] в map [someStruct] string , но они не совсем решают эту проблему.

Мой первый пользовательский типявляется строкой, а other является картой этого пользовательского типа для целочисленных значений. Пример кода ниже:

package main

import (
    "fmt"
)

type GlobalRuleName string
type RuleConf map[GlobalRuleName]int

func demo(ruleConf RuleConf) {
    fmt.Printf("ruleConf is %+v", ruleConf)
}

func main() {
    var dummyRuleName GlobalRuleName
    dummyRuleName = "dummy"

    dummyRuleConf := make(map[GlobalRuleName]int)
    dummyRuleConf[dummyRuleName] = 23
    demo(dummyRuleConf)

}

Это нормально работает с выводом ruleConf is map[dummy:23] Моя путаница заключается в том, почему переменная dummyRuleConf автоматически распознается как правило ruleConf от Go? Я ожидал, что демонстрационная функция выдаст ошибку, говоря, что ожидается тип ruleConf.

Это не работает со строками так же. Например: если я объявляю функцию, принимающую GlobalRuleName, и передаю ей строку, она выдает ошибку. Пример кода ниже:

func demoName(name GlobalRuleName) {
    fmt.Printf("name is %+v", name)

}

and then within main 
foo := "foo"
demoName(foo)
./prog.go:30:10: cannot use foo (type string) as type GlobalRuleName in argument to demoName

Полная ссылка на игровую площадку здесь: https://play.golang.org/p/WWO1H5MgLyJ

Почему удалось понять, что объявление карты dummyRuleConf соответствует пользовательскому типу для ruleConf, но не сделать это длястрока?

Fyi - я создал собственный тип для строк, потому что он делает мой код легче для понимания. Я читал в других сообщениях SO, что это не рекомендуется в Go, избавлюсь от него.

Мне нужно создать пользовательский тип для карты, так как я хочу написать методы для этого типа.

1 Ответ

0 голосов
/ 17 октября 2019

Ваш первый фрагмент кода работает, потому что вы уже объявили, что ваша переменная dummyRuleName имеет тип GlobalRuleName перед присваиванием. Таким образом, компилятор знает, что dummyRuleName может использоваться в качестве ключа в RuleConf.

Go - строго типизированный язык. Не существует автоматического приведения типов между различными типами переменных. Вам необходимо явно ввести переменные, чтобы сделать их назначаемыми друг другу, даже если базовый тип одинаков. Например,

var foo GlobalRuleName
foo = "foo" // because "foo" string literal is not a defined type
demoName(foo)

или

foo := GlobalRuleName("foo")
demoName(foo)

Вы также можете привести переменную при использовании :

foo := "foo"
demoName(GlobalRuleName(foo))
...