Сложный условный оператор в golang

Недавно я начал изучать голанг и Ревель. Я пытаюсь понять, что именно делает оператор if ниже. Похоже, он выполняет проверку типа, но я не вижу, что достигается условием. Благодарю, если кто-нибудь может сказать мне, что здесь происходит. Благодарность

if str, ok := obj.(string); ok {
return len(str) > 0
}

person broun    schedule 08.06.2014    source источник


Ответы (2)


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

Написанный более редко, это можно рассматривать как:

// do a type assertion/conversion of obj to a string. 
// If obj isn't really a string, ok will be false
str, ok := obj.(string) 

// this will only run if we're talking about a string
if ok {
 return len(str) > 0
}

Go делает безопасное приведение от некоторого интерфейса к реальному типу. Если вы сделаете это без части ok, ваша программа запаникует, если obj не является строкой. т.е. этот код приведет к сбою вашей программы, если obj не является строкой:

str := obj.(string) 
return len(str) > 0   

Вы можете узнать больше об утверждениях типов в документации:

http://golang.org/ref/spec#Type_assertions

person Not_a_Golfer    schedule 08.06.2014
comment
Ах!! имеет смысл, спасибо за быстрый ответ. - person broun; 09.06.2014

Это называется утверждением типа . Ваша переменная obj - это interface{}, другими словами, ее реальный тип может меняться от одного выполнения к другому. Утверждение типа используется для определения реального типа interface{}. Это можно сделать двумя способами:

str = obj.(string)

Это небезопасно: если когда-либо obj не string, программа запаникует. Другой - тот, который вы использовали в своем коде. Если obj не является string, логическое значение ok будет false.

Например:

func f(v interface{}) {
    if _, ok := v.(string); ok {
        fmt.Println("v is a string!")
    } else if _, ok := v.(float64); ok {
        fmt.Println("v is a float64!")
    } else {
         fmt.Println("v is something else...")
    }
}
f(17.42) // "v is a float64!"
f("foobar") // "v is a string!"
f([]string{"hello", "world"}) // "v is something else..."
person julienc    schedule 08.06.2014
comment
[]interface{} следует заменить на interface{}. str и if следует использовать, например. fmt.Println(str) и fmt.Println(if). - person Tom L; 24.04.2020