2015-11-20 4 views
2

Я новичок в языке Go и задавался вопросом, почему следующий фрагмент кода не работает;Переменная GoLang in for loop undefined outside

package main 

import (
    "fmt" 
) 

func main() { 
    for i := 0; i < 10000; i++ { 
     var randomString = fmt.Sprintf("a%sa\n", "test") 
    } 
    fmt.Printf("Made 10000 random strings like", randomString); 
} 

Я удалил некоторый не имеющий отношения код (поскольку это, очевидно, не является случайным).

Проблема, с которой я сталкиваюсь, заключается в том, что как раз под циклом for, «randomString» не определен.

Я пробовал установить его с помощью randomString := fmt.Sprintf() и с var, который вы видели выше.

Я вполне уверен, что это проблема определения области (переменная randomString не входит в область вне цикла for), но, как разработчик PHP/JS, я не привык к этому и сказал бы, что переменная также доступна после цикла for.

Как я могу получить доступ к этой переменной из этой точки? В основном просто отображается последняя сгенерированная строка.

ответ

2

См соответствующий раздел из спецификации: Declarations and scope:

Объем постоянной или переменной идентификатора объявленной внутри функции начинается в конце ConstSpec или VarSpec (ShortVarDecl для коротких объявлений переменных) и заканчивается в конце самого внутреннего блока, содержащего блок.

Определить его в область, в которой вы хотите получить доступ к нему: до for (в области видимости функции main()).

Также обратите внимание на то, что для fmt.Sprintf() требуется дополнительный параметр, кроме тех, которые нужно напечатать: строка формата. Либо укажите строку формата (например, укажите глагол %s для параметра randomString), либо вы можете использовать fmt.Sprintln().

func main() { 
    var randomString string 
    for i := 0; i < 10000; i++ { 
     randomString = fmt.Sprintf("a%sa\n", "test") 
    } 
    fmt.Println("Made 10000 random strings like", randomString) 
} 

Выход:

Made 10000 random strings like atesta 

Попробуйте на Go Playground.

+0

Ах! Это было так очевидно, что я этого не видел. Отлично, спасибо :) –

+0

И действительно, я забыл% s в отформатированной строке. Но Println хорошо работает и для этого. –

1

Это проблема определения области, в поле «Перейти» с областью randomString - это тело цикла, в JS это была бы целая функция. Правила оглавления различаются на разных языках.

Проверьте Go спецификации:

https://golang.org/ref/spec#Declarations_and_scope

+0

Спасибо, но я проверил эту страницу, прежде чем задавать вопрос - это не прояснило меня. Я знал, что у меня есть проблемы с охватом, поэтому я спросил. –

+0

@RobQuist Соответствующей частью для этого случая будет «Объем константного или переменного идентификатора, объявленного внутри функции, начинается в конце ConstSpec или VarSpec (ShortVarDecl для коротких объявлений переменных) и заканчивается в конце самого внутреннего содержащего блока «. – chill

+0

ах, я вижу, это было упомянуто выше .. – chill