Swift: guard let vs if let
Swift: guard let vs if let
我一直在 Swift 中阅读有关 Optionals 的内容,并且我看到了一些示例,其中 if let
用于检查 Optional 是否包含一个值,如果它包含 - 对展开值。
但是,我看到在 Swift 2.0 中关键字 guard let
被最常使用。我想知道 if let
是否已从 Swift 2.0 中删除,或者是否仍然可以使用。
我应该将包含 if let
的程序更改为 guard let
吗?
if let
和 guard let
有相似但不同的用途。
guard
的 "else" 情况必须退出当前范围。通常这意味着它必须调用 return
或中止程序。 guard
用于提前提供 return 而无需嵌套其余函数。
if let
嵌套它的作用域,不需要任何特殊的东西。可以return
也可以不
一般来说,如果 if-let
块将成为函数的其余部分,或者它的 else
子句将包含 return
或中止,那么您应该改用 guard
。这通常意味着(至少根据我的经验),当有疑问时,guard
通常是更好的答案。但是在很多情况下 if let
仍然是合适的。
何时使用 if-let
以及何时使用 guard
通常是风格问题。
假设您有 func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
和一个可选的项目数组 (var optionalArray: [SomeType]?
),并且您需要 return 或者 0
如果数组是 nil
(未设置)或 count
如果数组有值(已设置)。
你可以像这样使用 if-let
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
if let array = optionalArray {
return array.count
}
return 0
}
或者像这样使用 guard
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
guard let array = optionalArray else {
return 0
}
return array.count
}
这些示例在功能上是相同的。
guard
真正发挥作用的地方是当您执行验证数据之类的任务时,并且您希望函数在出现任何错误时尽早失败。
而不是在你接近完成验证时嵌套一堆 if-let
,"success path" 和现在成功绑定的可选值都在方法的主要范围内,因为失败路径已经全部 returned。
我将尝试用一些(未优化的)代码来解释 guard 语句的用处。
您有一个 UI,您在其中验证用户注册的文本字段,包括名字、姓氏、电子邮件、phone 和密码。
如果任何 textField 不包含有效文本,它应该使该字段成为 firstResponder。
这里是未优化的代码:
//pyramid of doom
func validateFieldsAndContinueRegistration() {
if let firstNameString = firstName.text where firstNameString.characters.count > 0{
if let lastNameString = lastName.text where lastNameString.characters.count > 0{
if let emailString = email.text where emailString.characters.count > 3 && emailString.containsString("@") && emailString.containsString(".") {
if let passwordString = password.text where passwordString.characters.count > 7{
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
} else {
password.becomeFirstResponder()
}
} else {
email.becomeFirstResponder()
}
} else {
lastName.becomeFirstResponder()
}
} else {
firstName.becomeFirstResponder()
}
}
您可以在上面看到,所有字符串(firstNameString、lastNameString 等)只能在 if 语句的范围内访问。所以它创建了这个 "pyramid of doom" 并且它有很多问题,包括可读性和易于移动的东西(如果字段的顺序被改变,你必须重写大部分代码)
使用 guard 语句(在下面的代码中),如果所有字段都有效,您可以看到这些字符串在 {}
之外可用并被使用。
// guard let no pyramid of doom
func validateFieldsAndContinueRegistration() {
guard let firstNameString = firstName.text where firstNameString.characters.count > 0 else {
firstName.becomeFirstResponder()
return
}
guard let lastNameString = lastName.text where lastNameString.characters.count > 0 else {
lastName.becomeFirstResponder()
return
}
guard let emailString = email.text where
emailString.characters.count > 3 &&
emailString.containsString("@") &&
emailString.containsString(".") else {
email.becomeFirstResponder()
return
}
guard let passwordString = password.text where passwordString.characters.count > 7 else {
password.becomeFirstResponder()
return
}
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
}
如果字段的顺序发生变化,只需向上或向下移动相应的代码行,就可以了。
这是一个非常简单的解释和一个用例。希望这对您有所帮助!
Guard 可以提高清晰度
当您使用 guard 时,您对 guard 的 更高 期望 成功 并且重要的是,如果它不成功成功,那么你只想退出作用域 early。就像你守卫看是否存在 file/image,数组是否为空。
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
如果你用 if-let 编写上面的代码,它会向阅读开发人员传达它更像是 50-50。但是如果你使用 guard,你会在你的代码中添加 clarity,这意味着我希望它在 95% 的时间内都能正常工作……如果它失败了,我不知道为什么会这样;这不太可能......但随后只需使用此默认图像代替,或者可能只是用一条有意义的消息断言,描述出了什么问题!
Avoid guard
s when they create side effects, guards are to be used as a natural flow. Avoid guards when else
clauses introduce side effects.
Guards establish required conditions for code to execute properly,
offering early exit
When you perform significant computation in the positive branch, refactor from if
to a guard
statement and returns the fallback value
in the else
clause
此外,由于上述建议和干净的代码,您 更有可能 want/need 将断言添加到 failed guard 语句,它只是提高了可读性,并让其他开发人员清楚你的期望。
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
From: Erica Sadun's Swift Style book + some modifications
(你不会用 asserts/preconditions if-let
秒。它看起来不对)
使用守卫还可以通过避免金字塔 厄运来帮助您提高清晰度。参见 。
Guard 通过在当前范围内创建一个 new 变量来避免嵌套
有一个重要的区别,我相信没有人解释清楚。
guard let
和 if let
展开 变量
使用 guard let
,您 正在创建 一个将 存在 的新变量。
使用 if let
,您只是在代码块内创建了一个新变量。
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
有关 if let
的更多信息,请参阅:
Guard 需要 范围退出
(在 Rob Napier 的回答中也提到):
您必须 guard
在 中定义一个函数。它的主要目的是abort/return/exit范围,如果条件不满足:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
对于 if let
你不需要把它放在任何 func:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
对比 if
值得注意的是,把这道题看成guard let
vs if let
和guard
vs if
.
更合适
独立 if
不进行任何展开,独立 guard
也不进行。请参见下面的示例。如果值为 nil
,它不会提前退出。没有可选值。如果不满足条件,它就会提前退出。
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
基本区别
后卫让
- 范围内的早期存在进程
- 要求范围存在,如
return
、throw
等
- 创建一个可以在作用域外访问的新变量。
如果让
- 范围外无法访问
- 不需要
return
声明。但是我们可以这样写
注意:两者都用于解包 Optional 变量。
我看到的最清楚的解释是 Github Swift Style Guide:
if
增加一层深度:
if n.isNumber {
// Use n here
} else {
return
}
guard
没有:
guard n.isNumber else {
return
}
// Use n here
A guard
statement is used to transfer program control out of a scope
if one or more conditions aren’t met.
The value of any condition in a guard
statement must be of type Bool
or a type bridged to Bool
. The condition can also be an optional
binding declaration.
保护语句具有以下形式:
guard condition else {
//Generally return
}
- Also popular as optional binding.
- For accessing optional object we use
if let
.
if let roomCount = optionalValue {
print("roomCount available")
} else {
print("roomCount is nil")
}
我从 swift 和 Bob 那里学到了这个..
典型Else-If
func checkDrinkingAge() {
let canDrink = true
if canDrink {
print("You may enter")
// More Code
// More Code
// More Code
} else {
// More Code
// More Code
// More Code
print("Let me take you to the jail")
}
}
Else-If
的问题
- 嵌套括号
- 必须阅读每一行才能发现错误消息
保护声明
保护块仅在条件为假时运行,并且它将通过 return 退出函数。如果条件为真,Swift 忽略保护块。它提供了提前退出和更少的括号。+
func checkDrinkProgram() {
let iCanDrink = true
guard iCanDrink else {
// if iCanDrink == false, run this block
print("Let's me take you to the jail")
return
}
print("You may drink")
// You may move on
// Come on.
// You may leave
// You don't need to read this.
// Only one bracket on the bottom: feeling zen.
}
用Else-If
解包可选
guard 语句不仅可用于用 else-if 语句替换典型的条件块,而且对于通过最小化括号数量来解包选项也很有用。为了比较,让我们首先开始如何用 else-if 解包多个可选值。
首先,让我们创建三个将被展开的可选项。
var publicName: String? = "Bob Lee"
var publicPhoto: String? = "Bob's Face"
var publicAge: Int? = nil
最可怕的噩梦
func unwrapOneByOne() {
if let name = publicName {
if let photo = publicPhoto {
if let age = publicAge {
print("Bob: \(name), \(photo), \(age)")
} else {
print("age is mising")
}
} else {
print("photo is missing")
}
} else {
print("name is missing")
}
}
上面的代码确实有效,但违反了DRY原则。太残忍了。让我们分解一下。+
稍微好一点
下面的代码比上面的代码更具可读性。+
func unwrapBetter() {
if let name = publicName {
print("Yes name")
} else {
print("No name")
return
}
if let photo = publicPhoto {
print("Yes photo")
} else {
print("No photo")
return
}
if let age = publicAge {
print("Yes age")
} else {
print("No age")
return
}
}
用 Guard 解包
else-if 语句可以替换为 guard.+
func unwrapOneByOneWithGuard() {
guard let name = publicName else {
print("Name missing")
return
}
guard let photo = publicPhoto else {
print("Photo missing")
return
}
guard let age = publicAge else {
print("Age missing")
return
}
print(name)
print(photo)
print(age)
}
用Else-If展开多个可选
到目前为止,您一直在一个一个地解包可选值。 Swift 允许我们一次解包多个可选值。如果其中一个包含nil,则执行else块。
func unwrap() {
if let name = publicName, let photo = publicPhoto, let age = publicAge {
print("Your name is \(name). I see your face right here, \(photo), you are \(age)")
} else {
// if any one of those is missing
print("Something is missing")
}
}
Be aware that when you unwrap multiple optionals at once, you can't identify which contains nil
使用 Guard 解包多个可选值
当然要用guard over else-if.+
func unwrapWithGuard() {
guard let name = publicName, let photo = publicPhoto, let age = publicAge else {
// if one or two of the variables contain "nil"
print("Something is missing")
return
}
print("Your name is \(name). I see your, \(photo). You are \(age).")
// Animation Logic
// Networking
// More Code, but still zen
}
guard let vs if let
func anyValue(_ value:String?) -> String {
guard let string = value else {
return ""
}
return string
}
func anyValue(_ value:String?) -> String {
if let string = value {
return string
}
return ""
}
我一直在 Swift 中阅读有关 Optionals 的内容,并且我看到了一些示例,其中 if let
用于检查 Optional 是否包含一个值,如果它包含 - 对展开值。
但是,我看到在 Swift 2.0 中关键字 guard let
被最常使用。我想知道 if let
是否已从 Swift 2.0 中删除,或者是否仍然可以使用。
我应该将包含 if let
的程序更改为 guard let
吗?
if let
和 guard let
有相似但不同的用途。
guard
的 "else" 情况必须退出当前范围。通常这意味着它必须调用 return
或中止程序。 guard
用于提前提供 return 而无需嵌套其余函数。
if let
嵌套它的作用域,不需要任何特殊的东西。可以return
也可以不
一般来说,如果 if-let
块将成为函数的其余部分,或者它的 else
子句将包含 return
或中止,那么您应该改用 guard
。这通常意味着(至少根据我的经验),当有疑问时,guard
通常是更好的答案。但是在很多情况下 if let
仍然是合适的。
何时使用 if-let
以及何时使用 guard
通常是风格问题。
假设您有 func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
和一个可选的项目数组 (var optionalArray: [SomeType]?
),并且您需要 return 或者 0
如果数组是 nil
(未设置)或 count
如果数组有值(已设置)。
你可以像这样使用 if-let
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
if let array = optionalArray {
return array.count
}
return 0
}
或者像这样使用 guard
:
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
guard let array = optionalArray else {
return 0
}
return array.count
}
这些示例在功能上是相同的。
guard
真正发挥作用的地方是当您执行验证数据之类的任务时,并且您希望函数在出现任何错误时尽早失败。
而不是在你接近完成验证时嵌套一堆 if-let
,"success path" 和现在成功绑定的可选值都在方法的主要范围内,因为失败路径已经全部 returned。
我将尝试用一些(未优化的)代码来解释 guard 语句的用处。
您有一个 UI,您在其中验证用户注册的文本字段,包括名字、姓氏、电子邮件、phone 和密码。
如果任何 textField 不包含有效文本,它应该使该字段成为 firstResponder。
这里是未优化的代码:
//pyramid of doom
func validateFieldsAndContinueRegistration() {
if let firstNameString = firstName.text where firstNameString.characters.count > 0{
if let lastNameString = lastName.text where lastNameString.characters.count > 0{
if let emailString = email.text where emailString.characters.count > 3 && emailString.containsString("@") && emailString.containsString(".") {
if let passwordString = password.text where passwordString.characters.count > 7{
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
} else {
password.becomeFirstResponder()
}
} else {
email.becomeFirstResponder()
}
} else {
lastName.becomeFirstResponder()
}
} else {
firstName.becomeFirstResponder()
}
}
您可以在上面看到,所有字符串(firstNameString、lastNameString 等)只能在 if 语句的范围内访问。所以它创建了这个 "pyramid of doom" 并且它有很多问题,包括可读性和易于移动的东西(如果字段的顺序被改变,你必须重写大部分代码)
使用 guard 语句(在下面的代码中),如果所有字段都有效,您可以看到这些字符串在 {}
之外可用并被使用。
// guard let no pyramid of doom
func validateFieldsAndContinueRegistration() {
guard let firstNameString = firstName.text where firstNameString.characters.count > 0 else {
firstName.becomeFirstResponder()
return
}
guard let lastNameString = lastName.text where lastNameString.characters.count > 0 else {
lastName.becomeFirstResponder()
return
}
guard let emailString = email.text where
emailString.characters.count > 3 &&
emailString.containsString("@") &&
emailString.containsString(".") else {
email.becomeFirstResponder()
return
}
guard let passwordString = password.text where passwordString.characters.count > 7 else {
password.becomeFirstResponder()
return
}
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
}
如果字段的顺序发生变化,只需向上或向下移动相应的代码行,就可以了。
这是一个非常简单的解释和一个用例。希望这对您有所帮助!
Guard 可以提高清晰度
当您使用 guard 时,您对 guard 的 更高 期望 成功 并且重要的是,如果它不成功成功,那么你只想退出作用域 early。就像你守卫看是否存在 file/image,数组是否为空。
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
如果你用 if-let 编写上面的代码,它会向阅读开发人员传达它更像是 50-50。但是如果你使用 guard,你会在你的代码中添加 clarity,这意味着我希望它在 95% 的时间内都能正常工作……如果它失败了,我不知道为什么会这样;这不太可能......但随后只需使用此默认图像代替,或者可能只是用一条有意义的消息断言,描述出了什么问题!
Avoid
guard
s when they create side effects, guards are to be used as a natural flow. Avoid guards whenelse
clauses introduce side effects. Guards establish required conditions for code to execute properly, offering early exitWhen you perform significant computation in the positive branch, refactor from
if
to aguard
statement and returns the fallback value in theelse
clause
此外,由于上述建议和干净的代码,您 更有可能 want/need 将断言添加到 failed guard 语句,它只是提高了可读性,并让其他开发人员清楚你的期望。
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS assertionFailure("Missing \(selectedImageName) asset") return } guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO return }
From: Erica Sadun's Swift Style book + some modifications
(你不会用 asserts/preconditions if-let
秒。它看起来不对)
使用守卫还可以通过避免金字塔 厄运来帮助您提高清晰度。参见
Guard 通过在当前范围内创建一个 new 变量来避免嵌套
有一个重要的区别,我相信没有人解释清楚。
guard let
和 if let
展开 变量
使用 guard let
,您 正在创建 一个将 存在 的新变量。
使用 if let
,您只是在代码块内创建了一个新变量。
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
有关 if let
的更多信息,请参阅:
Guard 需要 范围退出
(在 Rob Napier 的回答中也提到):
您必须 guard
在 中定义一个函数。它的主要目的是abort/return/exit范围,如果条件不满足:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
对于 if let
你不需要把它放在任何 func:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
对比 if
值得注意的是,把这道题看成guard let
vs if let
和guard
vs if
.
独立 if
不进行任何展开,独立 guard
也不进行。请参见下面的示例。如果值为 nil
,它不会提前退出。没有可选值。如果不满足条件,它就会提前退出。
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
基本区别
后卫让
- 范围内的早期存在进程
- 要求范围存在,如
return
、throw
等 - 创建一个可以在作用域外访问的新变量。
如果让
- 范围外无法访问
- 不需要
return
声明。但是我们可以这样写
注意:两者都用于解包 Optional 变量。
我看到的最清楚的解释是 Github Swift Style Guide:
if
增加一层深度:
if n.isNumber {
// Use n here
} else {
return
}
guard
没有:
guard n.isNumber else {
return
}
// Use n here
A
guard
statement is used to transfer program control out of a scope if one or more conditions aren’t met.The value of any condition in a
guard
statement must be of typeBool
or a type bridged toBool
. The condition can also be an optional binding declaration.
保护语句具有以下形式:
guard condition else {
//Generally return
}
- Also popular as optional binding.
- For accessing optional object we use
if let
.
if let roomCount = optionalValue {
print("roomCount available")
} else {
print("roomCount is nil")
}
我从 swift 和 Bob 那里学到了这个..
典型Else-If
func checkDrinkingAge() {
let canDrink = true
if canDrink {
print("You may enter")
// More Code
// More Code
// More Code
} else {
// More Code
// More Code
// More Code
print("Let me take you to the jail")
}
}
Else-If
的问题- 嵌套括号
- 必须阅读每一行才能发现错误消息
保护声明 保护块仅在条件为假时运行,并且它将通过 return 退出函数。如果条件为真,Swift 忽略保护块。它提供了提前退出和更少的括号。+
func checkDrinkProgram() {
let iCanDrink = true
guard iCanDrink else {
// if iCanDrink == false, run this block
print("Let's me take you to the jail")
return
}
print("You may drink")
// You may move on
// Come on.
// You may leave
// You don't need to read this.
// Only one bracket on the bottom: feeling zen.
}
用Else-If
解包可选guard 语句不仅可用于用 else-if 语句替换典型的条件块,而且对于通过最小化括号数量来解包选项也很有用。为了比较,让我们首先开始如何用 else-if 解包多个可选值。 首先,让我们创建三个将被展开的可选项。
var publicName: String? = "Bob Lee"
var publicPhoto: String? = "Bob's Face"
var publicAge: Int? = nil
最可怕的噩梦
func unwrapOneByOne() {
if let name = publicName {
if let photo = publicPhoto {
if let age = publicAge {
print("Bob: \(name), \(photo), \(age)")
} else {
print("age is mising")
}
} else {
print("photo is missing")
}
} else {
print("name is missing")
}
}
上面的代码确实有效,但违反了DRY原则。太残忍了。让我们分解一下。+
稍微好一点 下面的代码比上面的代码更具可读性。+
func unwrapBetter() {
if let name = publicName {
print("Yes name")
} else {
print("No name")
return
}
if let photo = publicPhoto {
print("Yes photo")
} else {
print("No photo")
return
}
if let age = publicAge {
print("Yes age")
} else {
print("No age")
return
}
}
用 Guard 解包 else-if 语句可以替换为 guard.+
func unwrapOneByOneWithGuard() {
guard let name = publicName else {
print("Name missing")
return
}
guard let photo = publicPhoto else {
print("Photo missing")
return
}
guard let age = publicAge else {
print("Age missing")
return
}
print(name)
print(photo)
print(age)
}
用Else-If展开多个可选 到目前为止,您一直在一个一个地解包可选值。 Swift 允许我们一次解包多个可选值。如果其中一个包含nil,则执行else块。
func unwrap() {
if let name = publicName, let photo = publicPhoto, let age = publicAge {
print("Your name is \(name). I see your face right here, \(photo), you are \(age)")
} else {
// if any one of those is missing
print("Something is missing")
}
}
Be aware that when you unwrap multiple optionals at once, you can't identify which contains nil
使用 Guard 解包多个可选值 当然要用guard over else-if.+
func unwrapWithGuard() {
guard let name = publicName, let photo = publicPhoto, let age = publicAge else {
// if one or two of the variables contain "nil"
print("Something is missing")
return
}
print("Your name is \(name). I see your, \(photo). You are \(age).")
// Animation Logic
// Networking
// More Code, but still zen
}
guard let vs if let
func anyValue(_ value:String?) -> String {
guard let string = value else {
return ""
}
return string
}
func anyValue(_ value:String?) -> String {
if let string = value {
return string
}
return ""
}