Именованные и Неименованные типы

проблема:

недавно я начал читать Голанг Механическая Спецификация и застрял, пытаясь понять по имени и без имени типы соответствующий раздел. Я пришел из динамического языка, и это дало мне немного головной боли.

на:

тип определяет набор значений и операций, специфичных для значений этого типа. Типы могут быть имени или безымянный. Именованные типы определяются a (возможно квалификации) имя типа; указываются неназванные типы использование литерала типа, который создает новый тип из существующих типов.

и продолжает:

именованные экземпляры логического, числового и строкового типов predeclared. Составные типы-массив, структура, указатель, функция, интерфейс, срез, карта и типы каналов - могут быть построены с использованием литералов типов.

проблема здесь в том, что со спецификацией ссылки заставляют меня прыгать по страницам и терять след того, что есть, с таким количеством концепций, брошенных на меня слишком быстро.


Другие Ресурсы:

Я искал разъяснения по этому поводу и, за исключением руководства по спецификации, ресурсы скудны. Единственным подходящим материалом, который я смог найти, было:--11-->

  • Обучение Go-Types - блог-сообщение, объясняющее нюансы системы типов в Go.

  • сюда о почти то же самое, что я прошу.

к сожалению, я не нашел соответствующие вопросы о переполнении стека относительно этого. (и если они существуют, мне нужно пересмотреть мои методы поиска!). Я спрашиваю, потому что понимание системы типов нового языка является одним из Основные понятия для того чтобы эффективно изучать его.


Итак, вопрос:

может кто-нибудь представить краткий, ясный пример, иллюстрирующий различия между понятиями именованный и неназванный типы?*

*кроме того, объясняя понятия квалификации и заранее заявленный было бы хорошо для полноты, но, очевидно, не обязательно.

2 ответов


простой способ думать об этом является то, что названные типы определяются с type оператор и неназванные типы являются составными типами, определенными литералом типа.

например, тип переменной x безымянный:

var x struct{ I int }

и тип переменной y называется:

type Foo struct{ I int }
var y Foo

считается, что каждая из этих переменных имеет отдельный тип, даже если базовый тип каждой из них одинаков (структура содержит один целочисленный элемент с именем I).

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

var x2 struct{ I int }
type Bar struct{ I int }
var z Bar

здесь x и x2 иметь тот же тип, в то время как y и z нет.

эти различия вступают в игру в нескольких местах в язык:

  1. назначение значения одного именованного типа переменной другого именованного типа запрещено, даже если базовый тип тот же. Однако допускается назначение между связанными именованными и неназванными типами. То есть, следующие в порядке:

    x = y    // named type assigned to unnamed type
    y = x    // unnamed type assigned to named type
    

    но следующее сообщение об ошибке:

    y = z    // assignment between different named types
    
  2. вы можете определить методы для типа, который вы назвали. Итак, добавление методов в Foo возможно, но нет способ присоединения методов к переменной x.

Обратите также внимание, что именованные типы могут использоваться в литералах типов для определения новых неназванных типов. Например, тип среза []Foo безымянный, несмотря на использование Foo. Если мы хотим прикрепить методы к этому типу среза (например, для использования с sort пакет), мы должны были бы назвать его:

type Baz []Foo

для начала спецификация языка-это то, что она звучит как -- справочный документ. Это отличный инструмент для справки, но не для изучения языка. ты лучше обучение о пройдите через Go Tour, интерактивное введение в различные аспекты языка или через Эффективный Go, который подробно описывает, как использовать язык.

безымянный тип, просто тип, объявленный без имени с помощью введите literal, другими словами, примитивный тип, за которым следует список других типов, которые делают его внутри {}. Или, чтобы снова процитировать спецификацию, литерал типа "составляет новый тип из существующих типов"пример со структурами следует, но в то время как неназванная структура может быть редкой, каналы и карты (которые снова мало что делают сами по себе должны быть в составе из других типов) редко по имени.

package main

import "fmt"

type Named struct {
    x int
    y int
}

func main() {
    a := Named{1, 2}
    fmt.Println(a)

    b := struct{ x, y int }{1, 2}
    fmt.Println(b)
}