program tip

선택적 변수 인쇄

radiobox 2020. 7. 30. 10:17
반응형

선택적 변수 인쇄


이 코드 줄을 사용하려고합니다.

class Student {
    var name: String
    var age: Int?

    init(name: String) {
        self.name = name
    }

    func description() -> String {
        return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
    }
}

var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())

위 코드는 다음과 같이 생성됩니다

Daniel hides his age.
Daniel is Optional(18) years old.

내 질문은 선택 사항 (18)이있는 이유입니다. 선택 사항을 제거하고 인쇄하는 방법은 무엇입니까?

Daniel is 18 years old.

옵션이 실제로 무엇인지 이해해야합니다. 많은 스위프트 초보자 var age: Int?는 나이가 가치가 있거나없는 Int임을 의미한다고 생각 합니다. 그러나 연령은 Int를 보유하거나 보유하지 않을 수있는 선택 사항임을 의미합니다.

description()함수 에서 Int를 인쇄하지 않고 대신 Optional을 인쇄합니다. Int를 인쇄하려면 옵션을 풀어야합니다. "옵션 바인딩"을 사용하여 옵션을 풀 수 있습니다.

if let a = age {
 // a is an Int
}

Optional이 객체를 보유하고 있다고 확신하는 경우 "forced unwrapping"을 사용할 수 있습니다.

let a = age!

또는 예제에서 설명 함수에 이미 nil 테스트가 있으므로 다음과 같이 변경할 수 있습니다.

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}

선택 사항은 값이 유형에 해당하는지 Swift가 완전히 확실하지 않음을 의미합니다 (예 : Int? Swift는 숫자가 Int인지 완전히 확신하지 못합니다.

이를 제거하기 위해 사용할 수있는 세 가지 방법이 있습니다.

1) 유형이 완전히 확실하면 느낌표를 사용하여 다음과 같이 강제로 줄 바꿈을 해제 할 수 있습니다.

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

옵션을 강제로 줄 바꿈 해제하고 nil과 같으면 다음과 같은 충돌 오류가 발생할 수 있습니다.

여기에 이미지 설명을 입력하십시오

이것이 반드시 안전하지는 않으므로 다음과 같은 유형과 값을 확신 할 수없는 경우 충돌을 방지 할 수있는 방법이 있습니다.

방법 2와 3은이 문제를 방지합니다.

2) 암시 적으로 래핑되지 않은 옵션

 if let unwrappedAge = age {

 // continue in here

 }

래핑되지 않은 유형은 이제 Int 가 아닌 Int입니까? .

3) 가드 진술

 guard let unwrappedAge = age else { 
   // continue in here
 }

From here, you can go ahead and use the unwrapped variable. Make sure only to force unwrap (with an !), if you are sure of the type of the variable.

Good luck with your project!


For testing/debugging purposes I often want to output optionals as strings without always having to test for nil values, so I created a custom operator.

I improved things even further after reading this answer in another question.

fileprivate protocol _Optional {
    func unwrappedString() -> String
}

extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}

postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

Obviously the operator (and its attributes) can be tweaked to your liking, or you could make it a function instead. Anyway, this enables you to write simple code like this:

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

Integrating the other guy's protocol idea made it so this even works with nested optionals, which often occur when using optional chaining. For example:

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5

Update

Simply use me.age ?? "Unknown age!". It works in 3.0.2.

Old Answer

Without force unwrapping (no mach signal/crash if nil) another nice way of doing this would be:

(result["ip"] ?? "unavailable").description.

result["ip"] ?? "unavailable" should have work too, but it doesn't, not in 2.2 at least

Of course, replace "unavailable" with whatever suits you: "nil", "not found" etc


To unwrap optional use age! instead of age. Currently your are printing optional value that could be nil. Thats why it wrapped with Optional.


In swift Optional is something which can be nil in some cases. If you are 100% sure that a variable will have some value always and will not return nil the add ! with the variable to force unwrap it.

In other case if you are not much sure of value then add an if let block or guard to make sure that value exists otherwise it can result in a crash.

For if let block :

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

For guard statement :

guard is a conditional structure to return control if condition is not met.

I prefer to use guard over if let block in many situations as it allows us to return the function if a particular value does not exist. Like when there is a function where a variable is integral to exist, we can check for it in guard statement and return of it does not exist. i-e;

guard let abc = any_variable else { return }

We if variable exists the we can use 'abc' in the function outside guard scope.


age is optional type: Optional<Int> so if you compare it to nil it returns false every time if it has a value or if it hasn't. You need to unwrap the optional to get the value.

In your example you don't know is it contains any value so you can use this instead:

if let myAge = age {
    // there is a value and it's currently undraped and is stored in a constant
}
else {
   // no value
}

I did this to print the value of string (property) from another view controller.

ViewController.swift

var testString:NSString = "I am iOS Developer"

SecondViewController.swift

var obj:ViewController? = ViewController(nibName: "ViewController", bundle: nil)
print("The Value of String is \(obj!.testString)")

Result :

The Value of String is I am iOS Developer

When having a default value:

print("\(name) is \(age ?? 0) years old")

or when the name is optional:

print("\(name ?? "unknown") is \(age) years old")


Check out the guard statement:

for student in class {
    guard let age = student.age else { 
        continue 
     }
    // do something with age
}

I was getting the Optional("String") in my tableview cells.

The first answer is great. And helped me figure it out. Here is what I did, to help the rookies out there like me.

Since I am creating an array in my custom object, I know that it will always have items in the first position, so I can force unwrap it into another variable. Then use that variable to print, or in my case, set to the tableview cell text.

let description = workout.listOfStrings.first!
cell.textLabel?.text = description

Seems so simple now, but took me a while to figure out.


이것이이 질문에 대한 정확한 답은 아니지만 이런 종류의 문제에 대한 한 가지 이유입니다. 필자의 경우 "if let"및 "guard let"을 사용하여 String에서 Optional을 제거 할 수 없었습니다.

그래서 사용 AnyObject를 대신 모든 빠른 문자열에서 선택적 제거 할 수 있습니다.

답변 링크를 참조하십시오.

https://stackoverflow.com/a/51356716/8334818

참고 URL : https://stackoverflow.com/questions/25846561/printing-optional-variable

반응형