선택적 문자열 확장을 추가하는 방법은 무엇입니까?
다음과 같이 문자열 확장을 만들 수 있습니다.
extension String {
func someFunc -> Bool { ... }
}
하지만 선택적 문자열에 적용하려면 어떻게해야합니까?
var optionalString :String? = ""
optionalString!.someFunc() /* String? does not have a member someFunc */
Swift 3.1에서는 선택적 값에 확장을 추가 할 수도 있습니다.
extension Optional where Wrapped == String {
var isBlank: Bool {
return self?.isBlank ?? true
}
}
다음과 같이 할 수 있습니다.
protocol OptionalType { typealias A; var opt: A? { get } }
extension Optional: OptionalType { var opt: A? { return self } }
protocol StringType { var get: String { get } }
extension String: StringType { var get: String { return self } }
extension Optional where Wrapped: StringType {
func getOrElse(s: String) -> String {
return self.opt?.get ?? s
}
}
과:
let optStr: String? = nil
optStr.getOrElse("hello world")
그 이유는 당신은 제한 할 수 없습니다 Optional
또는 String
그들이이기 때문에 그 문제입니다 struct
. 각각에 대해 의사 프로토콜을 만들면 이제 원하는대로 제한 할 수 있습니다.
저는 스위프트가 초보자가 배우기 쉽 도록 많은 것을 포기 했거나 언어가 아직 충분히 성숙하지 않은 것 같습니다.
그에 대한 확장 Optional
은String
Swift 3부터는 확장 메서드를 선택 사항으로 직접 제한 할 수 없습니다 String
. Daniel Shin의 답변이 설명하는 것처럼 프로토콜로 동등한 결과를 얻을 수 있습니다.
그러나 모든 유형의 Optional에 확장 메서드를 만들 수 있으며 String
반환 값 이있는 몇 가지 유용한 메서드를 찾았습니다 . 이러한 확장은 값을 콘솔에 로깅하는 데 유용합니다. String
가능한 nil을 빈 문자열로 바꾸고 싶을 때 선택 사항 에 asStringOrEmpty ()를 사용했습니다 .
extension Optional {
func asStringOrEmpty() -> String {
switch self {
case .some(let value):
return String(describing: value)
case _:
return ""
}
}
func asStringOrNilText() -> String {
switch self {
case .some(let value):
return String(describing: value)
case _:
return "(nil)"
}
}
}
사용 예 :
var booleanValue: Bool?
var stringValue: String?
var intValue: Int?
print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")
booleanValue = true
stringValue = "text!"
intValue = 41
print("booleanValue: \(booleanValue.asStringOrNilText())")
print("stringValue: \(stringValue.asStringOrNilText())")
print("intValue: \(intValue.asStringOrNilText())")
콘솔 출력 :
booleanValue: (nil)
stringValue: (nil)
intValue: (nil)
booleanValue: true
stringValue: text!
intValue: 41
Optional
nil 포인터와 다름
이러한 확장은 an Optional
이 nil 포인터와 다르다는 것을 보여줍니다 . 는 Optional
A는 enum
특정 유형 (의 Wrapped
그것 함을 의미 또는 값을 포함하지 않는다). Optional
값을 포함하지 않아도 "컨테이너" 에 확장을 작성할 수 있습니다 .
Swift 선택적 선언에서 발췌
enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value.
case none
/// The presence of a value, stored as `Wrapped`.
case some(Wrapped)
...
}
코드에서 값의 부재는 일반적으로 nil
명시적인 것보다는 리터럴을 사용하여 작성됩니다..none
enumeration case.
extension Optional where Wrapped == String {
var isNil: Bool {
return self == nil
}
The above answer(written by @Vlad Hatko) works fine but in swift 4 there are some issues, so I changed it to this.
Swift 4.1에서 Optional is ambiguous for type lookup in this context
빌드 오류가 발생했습니다. 수정하려면 Swift 네임 스페이스를 유형에 명시 적으로 추가해야합니다.
extension Swift.Optional where Wrapped == String {
var isBlank: Bool {
return self?.isBlank ?? true
}
}
업데이트 : Swift 2 이상에서 작동하는 해결 방법은 다음을 참조하십시오.Daniel Shin’s answer
선택적 문자열은 그 자체가 유형이 아니므로 선택적 유형에 대한 확장을 만들 수 없습니다. Swift에서 an Optional
은 None
이거나 Some
값을 래핑 할 수있는 열거 형 (약간의 구문 설탕 포함)입니다 . String 메서드를 사용하려면 optionalString
. 이를 위해 선택적 체인을 쉽게 사용할 수 있습니다.
optionalString?.someFunc()
If optionalString
is not nil
, someFunc
will be called on it. An alternative (less concise) way of doing this is to use optional binding to establish whether or not optionalString
has a value before trying to call the method:
if let string = optionalString {
string.someFunc() // `string` is now of type `String` (not `String?`)
}
In your example from the comments below, you needn't nest multiple if
statements, you can check if the optional string is an empty string in a single if
:
if optionalString?.isEmpty == true {
doSomething()
}
This works because the expression optionalString?.isEmpty
returns an optional Bool (i.e. true
, false
or nil
). So doSomething()
will only be called if optionalString
is not nil
, and if that string is empty.
Another alternative would be:
if let string = optionalString where string.isEmpty {
doSomethingWithEmptyString(string)
}
Since Xcode 9.3, you can use this slight modification of @Vladyslav's answer:
extension Optional where Wrapped == String {
var isEmpty: Bool {
return self?.isEmpty ?? true
}
}
found some trick swift 3
class A{
var name:String!;
init(_ name:String?){
self.name = name;
}
}
extension Optional where Wrapped == String {
func compareText(_ other:String?)->Bool{
switch (self,other){
case let(a?,b?):
return a < b;
case (nil,_):
return true;
default:
return false;
}
}
}
let words:[A] = [A("a"),A(nil),A("b"),A("c"),A(nil)];
// let sorted = words.sorted{ 0.name.compareText($1.name) }
// trick
let sorted = words.sorted{ ($0.name as String?).compareText($1.name) }
print(sorted.map{$0.name});
참고URL : https://stackoverflow.com/questions/29462953/how-to-add-an-optional-string-extension
'development' 카테고리의 다른 글
C ++에서 열거 형 데이터의 크기는 얼마입니까? (0) | 2020.12.06 |
---|---|
별 5 개 등급을 계산하는 데 사용되는 알고리즘 (0) | 2020.12.06 |
RecyclerView의 ItemAnimator를 구현하여 notifyItemChanged 애니메이션을 비활성화하는 방법 (0) | 2020.12.06 |
오류 : com.google.gms : google-services : 1.0을 찾을 수 없습니다. (0) | 2020.12.06 |
'내부'보호 수준으로 인해 이니셜 라이저에 액세스 할 수 없습니다. (0) | 2020.12.06 |