Аналог defer в языке R

В Гоу есть интересная конструкция (defer) — её содержимое выполняется, когда заканчивает работу функция, в которой эта конструкция объявлена, очень удобно память освобождать или другие ресурсы. Я накидал небольшой пример, чтобы было понятно:
package main

import (
	"bufio"
	"fmt"
	"os"
)

func readFile(filename string) (out []string) {
	file, _ := os.Open(filename)
	defer file.Close()

	b := bufio.NewReader(file)

	for {
		if str, err := b.ReadString('\n'); err != nil {
			break
		} else {
			out = append(out, str)
		}
	}

	return out
}

func main() {
	var lines []string

	for _, line := range readFile("/etc/passwd") {
		if line[0] != '#' {
			lines = append(lines, line)
		}
	}

	fmt.Println(lines)
}
В примере одна функция построчно читает файл и возвращает массив строк. Её использует основная функция (main), чтобы прочитать файл с информацией о пользователях в системе, удалив оттуда комментарии — строки, начинающиеся с «#». Обработку ошибок я не стал делать — и без этого длинновато вышло.

В фунции чтения файла блок defer вызовется как только мы покинем функцию и закроет используемый файл. Такой способ лучше, чем отсутствующий «Гоу» блок try…finally, так как позволяет указать способ освобождения ресурса очень близко к началу его использования.

Есть языки, которые, на мой взгляд, решают эту задачу ещё лучше (например, Пайтон со своим with), но у Гоу своя атмосфера и выбранное решение отвечает духу языка.

«Эр» на «Гоу» совсем не похож, у языков совершенно разные идеологии, поэтому я очень удивился, обнаружив в «Эр» тот же подход, что выбран в «Гоу».Тот же пример на «Эре»:
readFile <- function(filename) {
	f <- file(filename, 'r')
	on.exit({
		close(f)
	})

	return(readLines(f))
}

lines <- readFile('/etc/passwd')
print(lines[!grepl('^#', lines)])
Конструкция on.exit делает тут ровно то же, что defer в «Гоу». Нельзя не заметить, что программа стала гораздо компактнее, но в многословности Гоу обвинить нельзя — всё-таки он более низкоуровневый, плюс статически типизированный, отсюда и более подробный код.
12 июня 2017 20:04

ufm (инкогнито)
20 июня 2017, 13:29

её содержимое вычисляется, когда мы уходим из текущего блока выполнения
Не совсем так.
_Вычисляется_ - в момент определения, если это параметр функции.
_Выполняется_ когда выходим из _функции_ (а не блока).

как пример: https://play.golang.org/p/nh4zIotAFY

bolknote.ru (bolknote.ru)
20 июня 2017, 16:03, ответ предназначен ufm

Действительно, с терминологией у меня тут полный швах, сейчас поправлю.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)