Например:
package package
// Dear user, CleanUp must only be used with defer: defer CleanUp()
func CleanUp() {
// some logic to check if call was deferred
// do tear down
}
И в пользовательском коде:
func main() {
package.CleanUp() // PANIC, CleanUp must be deferred!
}
Но все должно быть хорошо, если пользователь запускает:
func main() {
defer package.CleanUp() // good job, no panic
}
Вещи, которые я уже пробовал:
func DeferCleanUp() {
defer func() { /* do tear down */ }()
// But then I realized this was exactly the opposite of what I needed
// user doesn't need to call defer CleanUp anymore but...
}
// now if the APi is misused it can cause problems too:
defer DeferCleanUp() // a defer inception xD, question remains.
defer package.CleanUp()
, а затем вызвать эту функцию, фактически вызвав вашу функцию безdefer
(но на самом деле сdefer
). ). - person icktoofay   schedule 24.12.2014defer func(){ defer CleanUp() }
? Да, Санта ненавидит таких пользователей :) - person marcio   schedule 24.12.2014func() { defer CleanUp() }()
безdefer
перед внешней функцией. - person icktoofay   schedule 24.12.2014func main(){ defer CleanUp() }
. дыра заключается в том, чтобы обязать использовать функцию сdefer
. - person marcio   schedule 24.12.2014func main() { foo(); func() { defer CleanUp() }(); bar() }
, который, вероятно, будет вести себя точно так же, какfunc main() { foo(); CleanUp(); bar() }
, но все же будет соответствовать вашим ограничениям. - person icktoofay   schedule 24.12.2014CleanUp()
без отсрочки по отвлечению внимания, чтобы приложение немедленно запаниковало. Где он называется, не имеет большого значения. - person marcio   schedule 24.12.2014mutex.Unlock()
очень, очень часто откладывается сразу после соответствующегоmutex.Lock()
, но у него нет особого статуса отсрочки. Иногда нужно просто документировать. - person twotwotwo   schedule 24.12.2014