Comments 12
Если варить кашу из топора, она будет, скорее всего, вовсе не вкуснее каши без топора, и, быть может, будет иметь какой-то привкус — особенно в случае, если топор был грязный. В этой связи считаю топор инструментом бесполезным и даже немного вредным.
Искренне прошу прощения, не удержался. По делу: представьте себе, что вы делаете биндинги для сторонней библиотеки, написанной, например, на C. И в этой библиотеке какие-то объекты должны создаваться функциями create_XXX() (внутри вызывают malloc()) и освобождаться функциями free_XXX(). И вот, честно избегая SetFinalizer, мы пишем в документации, что, хотя Go — язык с GC, конкретно вот эти вот объекты, вследствие особенностей их внутренней реализации, надо обязательно освобождать через какой-нибудь Free(), при том, что эта функция/метод по своей сути не будет делать ничего, кроме освобождения памяти. Звучит логично? По-моему, нет. Как раз для оборачивания подобной логики управления памятью SetFinalizer подходит идеально.
Искренне прошу прощения, не удержался. По делу: представьте себе, что вы делаете биндинги для сторонней библиотеки, написанной, например, на C. И в этой библиотеке какие-то объекты должны создаваться функциями create_XXX() (внутри вызывают malloc()) и освобождаться функциями free_XXX(). И вот, честно избегая SetFinalizer, мы пишем в документации, что, хотя Go — язык с GC, конкретно вот эти вот объекты, вследствие особенностей их внутренней реализации, надо обязательно освобождать через какой-нибудь Free(), при том, что эта функция/метод по своей сути не будет делать ничего, кроме освобождения памяти. Звучит логично? По-моему, нет. Как раз для оборачивания подобной логики управления памятью SetFinalizer подходит идеально.
Спасибо, я думаю вы правы. Хотя я наверное все-равно вызывал бы явно.
Можете дать пример на гитхабе, я добавлю в статью?
Можете дать пример на гитхабе, я добавлю в статью?
Вот на вскидку из чьих-то биндингов для библиотеки exiv2: github.com/abustany/goexiv/blob/44f56aad5477a9e8dabe44270c99aeabffec7361/exiv.go#L53 «Дистиллированный» пример прямо сейчас нет времени писать, сорри, от компа уже убегаю.
Мне кажется, ваш пример некорректен. Если уж возвращать, то объект файла, а не дескриптор, тогда он и не помрет раньше времени.
В языке с GC ручное управление ресурсами это, честно говоря, дикость.
Но проблема здесь не в том, что файл закроется, а в том, что такое поведение недокументированно и совершенно неожиданно.
func (f *File) Fd() uintptr
Fd returns the integer Unix file descriptor referencing the open file. The file descriptor is valid only until f.Close is called or f is garbage collected.
Во многих языках возвращать нечто из кишков другого нечто — не самая хорошая идея. Тем более в случае, когда первое может пережить второе. Не понимаю, что здесь неожиданного.
Sign up to leave a comment.
Тайна финализаторов в Go