"with"함수 패턴을 사용하여 정리 논리를 통합하는 방법
"with"함수는 콜백을 받아 일부 초기화를 수행하고 콜백을 호출한 다음 일부 정리를 수행합니다.
예를 들어, 다음과 같이 모든 SQL 트랜잭션에 대해 수동으로
COMMIT
또는 ROLLBACK
를 수행하는 대신:tx, err := db.Begin()
if err != nil {
return err
}
err = tx.Exec("INSERT ...")
if err != nil {
// 💥 Oops, forgot tx.Rollback(), tx remains open!
return err
}
// execute more statements...
err = tx.Commit()
if err != nil {
return err
}
withTx()
함수를 만들 수 있습니다.func withTx(db DB, callback func(Tx) error) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
err = callback(tx)
if err != nil {
return err
}
return tx.Commit()
}
다음과 같이 사용하십시오.
err := withTx(db, func(tx Tx) error {
err = tx.Exec("INSERT ...")
if err != nil {
// 🙂 No need to remember to call tx.Rollback()
return err
}
// execute more statements...
})
if err != nil {
return err
}
언뜻 보기에 calls ~
Begin()
의 ~5%는 오류( likely example )에서 해당하는 Rollback()
가 누락된 것으로 보입니다. withTx()
함수를 사용하면 이러한 버그를 제거하는 데 도움이 됩니다.그리고 Go 제네릭을 사용하면
withTx
에서 값을 반환할 수 있습니다.-func withTx(db DB, callback func(Tx) error) error {
+func withTx[T any](db DB, callback func(Tx) (*T, error)) (*T, error) {
tx, err := db.Begin()
if err != nil {
- return err
+ return nil, err
}
defer tx.Rollback()
- err = callback(tx)
+ t, err := callback(tx)
if err != nil {
return err
}
- return tx.Commit()
+ return t, tx.Commit()
}
"with"함수 패턴의 이점:
명심해야 할 한 가지 주의 사항: 콜백이 리소스를 반환하지 않는지 확인해야 합니다. 그렇지 않으면 정리 실행 후 해당 리소스가 사용되어 오류가 발생할 수 있습니다! Go에서 컴파일 타임에 올바른 사용을 강제하는 것이 가능하다고 생각하지 않습니다. 그것은 Haskell에서 가능하지만(인체공학적이지는 않음) 내장된 가치 평생 기계에 편승하여 Rust에서 편리합니다.
Reference
이 문제에 관하여("with"함수 패턴을 사용하여 정리 논리를 통합하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/chrismwendt/how-to-consolidate-cleanup-logic-using-the-with-function-pattern-45nm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)