2015-02-09 2 views
3

Я только что прочитал blog, написанный Робом Пайком. У меня есть небольшой вопрос относительно этого, и может быть, я тоже ошибаюсь, но все равно хотел бы получить обратную связь и правильно разобраться с Go.Ошибки - значения (блог) - логически то же самое?

В блоге был фрагмент кода (который на самом деле был написан @jxck_)

_, err = fd.Write(p0[a:b]) 
if err != nil { 
    return err 
} 
_, err = fd.Write(p1[c:d]) 
if err != nil { 
    return err 
} 
_, err = fd.Write(p2[e:f]) 
if err != nil { 
    return err 
} 
// and so on 

а) В соответствии с моим пониманием выше код будет вернуться, если произошла ошибка при fd.Write(p0[a:b]), и никогда не будет выполнять fd.Write(p1[c:d]) , правильно?

И Роб предложил написать что-то вроде этого

var err error 
write := func(buf []byte) { 
    if err != nil { 
     return 
    } 
    _, err = w.Write(buf) 
} 
write(p0[a:b]) 
write(p1[c:d]) 
write(p2[e:f]) 
// and so on 
if err != nil { 
    return err 
} 

б) Исходя из вышеизложенного, выглядит как ошибка будет возвращаться из функции к югу. Значит это означает, что если ошибка возникает при write(p0[a:b]), то все равно она выполнит write(p1[c:d]), правильно? Значит, это логически и то, и другое не так, верно?

Никто не объясняет.

ответ

2

a) Да, вы правы. Если ошибка возникает при первой записи, она вернется.

b) Номер write в этом примере - closure. err внутри него такой же, как и во внешнем пространстве. Поэтому, если первая запись не удалась, другая просто вернется, потому что внешний err больше не nil.

+0

Согласен. Теперь я понимаю :-). –

+0

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

3

Нет, они такие же. Если error имеет значение fd.Write(p0[a:b]), переменная err будет удерживать свое значение.

Теперь, если вы звоните write(p1[c:d]), то write() FUNC сначала проверит, если err != nil, но так как он уже хранит error, которые произошли в предыдущем вызове, он будет немедленно вернуться и не будет выполнять дальнейший код.

+0

Согласен. Теперь я ясно :-) –

Смежные вопросы