如何将 try-catch 移动到处理所有 try-catch 逻辑以及 return 错误的 class?
How do I move try-catch into a class that handles all try-catch logic but also return errors?
我正在写一个基本的玩家 wallet
管理 class 其中 Integers
被添加(贷记)或减去(借记)到玩家的钱包,其中错误被一个简单的 try-catch
逻辑。
Note: It only is meant to handle Integers
.
我正试图将 try-catch
逻辑抽象到这个钱包 class 中;它应该处理任何带有 credit
、debit
操作、捕获错误和 return 错误(如果发现)。
有没有办法将 try-catch 内容移动到 class 但 return 的错误中?
让我们看一下这个例子:
我现在的class是这样的:
enum WalletError : Error {
case mustBePositive
case notEnoughFunds
}
class Wallet {
public private(set) var balance: Int = 0
init(amount: Int = 0) {
self.balance = amount
}
func credit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
handleCredit(amount: amount)
}
func debit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
guard balance >= amount else {
throw WalletError.notEnoughFunds
}
guard (self.balance - amount >= 0) else {
throw WalletError.notEnoughFunds
}
handleDebit(amount: amount)
}
// MARK: (Private)
private func handleCredit(amount: Int) {
self.balance += amount
}
private func handleDebit(amount: Int) {
self.balance -= amount
}
}
测试借记操作,我有这个XCTest
函数
func testDebit() {
let w = Wallet()
XCTAssertTrue(w.balance == 0)
// Can't debit negative numbers
XCTAssertThrowsError(try w.debit(amount: -100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// can't debit money you don't have
XCTAssertThrowsError(try w.debit(amount: 100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// credit 0
XCTAssertNoThrow(try w.credit(amount: 100))
// debit [=13=] should throw error
XCTAssertThrowsError(try w.debit(amount: 0)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// debit > balance should throw error
XCTAssertThrowsError(try w.debit(amount: 101)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// debit should be successful
XCTAssertNoThrow(try w.debit(amount: 1))
// balance should be 100-1 =
XCTAssertTrue(w.balance == 99)
}
我在这里遇到的问题是:
我写应用的时候每次都需要写try-catch块
我希望钱包 class 能够处理所有 try-catch 内容,并且只报告错误
我试过这个:
// changes to wallet class
func canCredit(amount: Int) throws -> Bool {
guard amount > 0 else {
throw WalletError.mustBePositive
}
return true
}
func credit(amount: Int) -> Error? {
do {
if ( try canCredit(amount: amount) ) {
handleCredit(amount: amount)
}
return nil
} catch let error {
return error
}
}
但是现在 XCTest
不知道抛出,我需要测试现在只有 returns true/false.
的 canCredit
此外,信用试图return错误,但我不能使用XCTAssertThrowsError()
有什么办法可以吗:
钱包class应该只负责信用、借记和验证
将我所有的 try-catch 逻辑都放到这里 class 这样我就不必一直重复 try-catch 了?
我希望我已经澄清了这个问题。
谢谢
制作函数throw
并交出错误
func credit(amount: Int) throws {
try canCredit(amount: amount)
handleCredit(amount: amount)
}
- 如果
canCredit
成功,代码将转到下一行并处理信用。
- 如果
canCredit
失败,接收到的错误将移交并退出函数。
您的目标似乎是将抛出的错误转换为返回的错误。这个目标似乎是错误的。抛出是一种流量控制形式。抛出一个错误 是 你如何 "return an error" 给调用者的。首先,你不应该想要你似乎想要的东西。
不过,你一定可以做到。首先,保持 credit(amount:)
和 debit(amount:)
方法与第一个代码示例中的方法完全相同,以便您的单元测试可以测试它们。其次,在您的 "real code" 中,不要调用这些方法。相反,调用您提供的其他 "wrapper" 方法,捕获抛出的错误并将其转换为返回的错误。
例如:
func realcredit(amount: Int) -> Error? {
do {
try credit(amount:amount)
return nil
} catch {
return error
}
}
我正在写一个基本的玩家 wallet
管理 class 其中 Integers
被添加(贷记)或减去(借记)到玩家的钱包,其中错误被一个简单的 try-catch
逻辑。
Note: It only is meant to handle
Integers
.
我正试图将 try-catch
逻辑抽象到这个钱包 class 中;它应该处理任何带有 credit
、debit
操作、捕获错误和 return 错误(如果发现)。
有没有办法将 try-catch 内容移动到 class 但 return 的错误中?
让我们看一下这个例子:
我现在的class是这样的:
enum WalletError : Error {
case mustBePositive
case notEnoughFunds
}
class Wallet {
public private(set) var balance: Int = 0
init(amount: Int = 0) {
self.balance = amount
}
func credit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
handleCredit(amount: amount)
}
func debit(amount: Int) throws {
guard amount > 0 else {
throw WalletError.mustBePositive
}
guard balance >= amount else {
throw WalletError.notEnoughFunds
}
guard (self.balance - amount >= 0) else {
throw WalletError.notEnoughFunds
}
handleDebit(amount: amount)
}
// MARK: (Private)
private func handleCredit(amount: Int) {
self.balance += amount
}
private func handleDebit(amount: Int) {
self.balance -= amount
}
}
测试借记操作,我有这个XCTest
函数
func testDebit() {
let w = Wallet()
XCTAssertTrue(w.balance == 0)
// Can't debit negative numbers
XCTAssertThrowsError(try w.debit(amount: -100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// can't debit money you don't have
XCTAssertThrowsError(try w.debit(amount: 100)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// credit 0
XCTAssertNoThrow(try w.credit(amount: 100))
// debit [=13=] should throw error
XCTAssertThrowsError(try w.debit(amount: 0)) { error in
XCTAssertEqual(error as? WalletError, WalletError.mustBePositive)
}
// debit > balance should throw error
XCTAssertThrowsError(try w.debit(amount: 101)) { error in
XCTAssertEqual(error as? WalletError, WalletError.notEnoughFunds)
}
// debit should be successful
XCTAssertNoThrow(try w.debit(amount: 1))
// balance should be 100-1 =
XCTAssertTrue(w.balance == 99)
}
我在这里遇到的问题是:
我写应用的时候每次都需要写try-catch块
我希望钱包 class 能够处理所有 try-catch 内容,并且只报告错误
我试过这个:
// changes to wallet class
func canCredit(amount: Int) throws -> Bool {
guard amount > 0 else {
throw WalletError.mustBePositive
}
return true
}
func credit(amount: Int) -> Error? {
do {
if ( try canCredit(amount: amount) ) {
handleCredit(amount: amount)
}
return nil
} catch let error {
return error
}
}
但是现在 XCTest
不知道抛出,我需要测试现在只有 returns true/false.
此外,信用试图return错误,但我不能使用XCTAssertThrowsError()
有什么办法可以吗:
钱包class应该只负责信用、借记和验证
将我所有的 try-catch 逻辑都放到这里 class 这样我就不必一直重复 try-catch 了?
我希望我已经澄清了这个问题。
谢谢
制作函数throw
并交出错误
func credit(amount: Int) throws {
try canCredit(amount: amount)
handleCredit(amount: amount)
}
- 如果
canCredit
成功,代码将转到下一行并处理信用。 - 如果
canCredit
失败,接收到的错误将移交并退出函数。
您的目标似乎是将抛出的错误转换为返回的错误。这个目标似乎是错误的。抛出是一种流量控制形式。抛出一个错误 是 你如何 "return an error" 给调用者的。首先,你不应该想要你似乎想要的东西。
不过,你一定可以做到。首先,保持 credit(amount:)
和 debit(amount:)
方法与第一个代码示例中的方法完全相同,以便您的单元测试可以测试它们。其次,在您的 "real code" 中,不要调用这些方法。相反,调用您提供的其他 "wrapper" 方法,捕获抛出的错误并将其转换为返回的错误。
例如:
func realcredit(amount: Int) -> Error? {
do {
try credit(amount:amount)
return nil
} catch {
return error
}
}