в данном случае отличается от классической рекурсии и какие тут затраты по памяти?
func PrintReversedSlice[T any](slice []T) {
for _, value := range slice {
defer fmt.Print(value)
}
}
Деферы срабатывают в обратном порядке вызова
это я понимаю, а где они хранятся? что в памяти и на стеке происходит?
When there are multiple deferred statements in the same function, they are stored and executed as a stack. Получается сброс параметров стека каждый раз когда вызов defer, тогда это даёт доп расходы на выполнение, значит такой код работает, но очень не оптимально https://www.sohamkamani.com/golang/defer/ Хотя не ясно как там происходит внутри тут сказано как стек, но насчёт куда они складываются? Я только предполагаю что в стек
интуиция подсказывает что defer это синтаксический сахар для рекурсии
а линтеры говорят, что так писать вообще не стоит Possible resource leak, 'defer' is called in the 'for' loop Inspection info: Reports defer statements inside loops. Using defer in loops can lead to resource leaks or unpredictable execution order of statements. Example: func main() { for { field, err := db.Query("SELECT 1") if err != nil { // ... } defer field.Close() // ... } } Calls of defer row.Close() inside the loop are not executed until the function completes its execution. Not at the end of each step of the for loop. Such implementation might lead to overflow of the function's stack and other issues.
Чет я идею вашу не пойму, причем тут рерурсия если рекурсия это вызов себя, а дефер какую-то другую функцию
я пытаюсь разобраться как работает этот код https://t.me/gogolang/704685 он похож на рекурсию, ведет себя как рекурсия, занимает память на стеке как рекурсия, но при этом рекурсией не является
Не ведёт он себя как рекурсия, просто создали много деферов
Значит в стек таки кладётся
Конечно кладется. В случае с циклом Go не может заинлайнить вызов по определению по сколько количество итераций определяется в рантайме
а что такое дефер? что делает рантайм когда я вызываю defer func() ?
то есть он не выходя за пределы стеково фрейма PrintReversedSlice подкидывает туда вызовы какой-то фукнции с аргументами? А как это может произойти в рантайме стек же должен быть определен еще до запуска программы? или компилятор этот цикл еще на этапе компиляции выполил?
Не могу знать, буду признателен если кто-нибудь кинет статейку. Был бы в го try finally я б сказал что дефер это стек функций (стек в данном случае структура данных) которую выполняет рантайм в блоке finally
нашел! https://kovardin.ru/articles/go/defer/
Обсуждают сегодня