Функция со значениями 1/2 и коротким объявлением переменной, дважды присваиваемая одной и той же переменной

#go

#Вперед

Вопрос:

У меня есть два вопроса к следующему коду

  1. emptyinterface.(int) может возвращать одно или два значения, как определяется функция для достижения этого эффекта?
  2. ok была объявлена дважды с использованием объявления короткой переменной, почему это возможно в этом контексте?
 package main

import (
    "fmt"
)

func main() {
    var emptyinterface interface{}
    emptyinterface=4

    i1:=emptyinterface.(int)
    fmt.Println(i1)
    i2,ok:=emptyinterface.(int)//<- how the function is defined such that it can return either 1 (i1) or 2 values (i2,ok)?
    fmt.Println(i2,ok)
    i3,ok:=emptyinterface.(string) //<--why I can reassign to ok, which has assign previously?
    fmt.Println(i3,ok)
}
  

Ответ №1:

  1. Это не функция, это языковая функция. Вы не можете написать функцию, которая это делает, но авторы компилятора могут создать немного синтаксиса, который это делает.

  2. A := недопустимо, если в его левой части нет новых переменных. Если объявляется хотя бы одна новая переменная, это разрешено.

Ответ №2:

В каждом из случаев создается по крайней мере новая переменная вместе с ok , т. е. i2 и i3 , Поэтому ok повторное объявление отлично.

Это хорошо задокументировано в спецификации языка (курсив мой) в разделе Короткие объявления переменных

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

Также неясно, что вы имеете в виду здесь как функцию, утверждение типа — это особенность языка, которая утверждает, имеет ли значение в интерфейсе определенный тип. Она всегда возвращает базовое значение, если утверждение было успешным, или сбой, если это не так. Вы всегда должны проверять возвращаемое значение утверждения типа (2-й аргумент), прежде чем использовать его в другом месте.