Quick type expression in methods that can throw and cannot

As you know, Swift can take types out of use. For example, you may have overloaded methods that differ only in the return type and use them freely if the compiler is able to infer the type. For example, using an additional explicitly typed variable that will contain the return value of such a method.

I found some fun points. Imagine this class:

class MyClass {
    enum MyError: Error {
        case notImplemented
        case someException
    }

    func fun1() throws -> Any {
        throw MyError.notImplemented
    }

    func fun1() -> Int {
        return 1
    }

    func fun2() throws -> Any {
        throw MyError.notImplemented
    }

    func fun2() throws -> Int {
        if false {
            throw MyError.someException
        } else {
            return 2
        }
    }
}

Of course, it will work as follows:

let myClass = MyClass()
// let resul1 = myClass.fun1() // error: ambiguous use of 'fun1()'
let result1: Int = myClass.fun1() // OK

But then you can write something like:

// print(myClass.fun1()) // error: call can throw but is not marked with 'try'
// BUT
print(try? myClass.fun1()) // warning: no calls to throwing functions occur within 'try' expression

therefore, it looks like mutual exclusive statements. The compiler is trying to choose the right function; with the first call, he tries to force a throw from Int to Any, but what does he try to do with the second?

In addition, type code

if let result2 = try? myClass.fun2() { // No warnings
    print(result2)
}

, , (, , ).

? fun1() ? , ?

+4
2

, . , , , , . , .

-, try - Swift. . . , , try. try . :

class X {
    func x() throws -> X {
        return self
    }
}

let y = try X().x().x()

try , . , , x() -. " ", try.

. :

let resul1 = myClass.fun1() // error: ambiguous use of 'fun1()'

Swift . Any or it could be Int`, .

( ):

let result1: Int = myClass.fun1() // OK

, ( no ?):

let x : Any = try myClass.fun1()

( )

let x : Any = try? myClass.fun1() // Expression implicitly coerced from `Int?` to `Any`
                                  // No calls to throwing function occur within 'try' expression

Int? try? ( Any). , Swift , Int? Any Any? Any. Swift Any ( Any?). Any . . , , Any - , .

, print? print Any, let x: Any =..., let x =....

, , :

  • T T?
  • T Any
  • T?
    • Any? ( Any??, Any???, Any???? ..)
    • ? (Any??, Any??? ..) Any
    • "" .

, / Any/Any? try? ( , ), .

, .

+5

Swift , .

, , Swift Any, , Any, let result2: Any = try? myClass.fun1(), fun1 Int, Any, fun1.

, Any, Any , .

let result2 = try? myClass.fun1() as Any //nil, since the function throws an error

, fun1,

func fun1() throws -> String {
    return ""
}

fun1 3 , :

let result1: Int = myClass.fun1() // 1
print(try? myClass.fun1()) //error: ambiguous use of 'fun1()'
let result2: Any = try? myClass.fun1() //error: ambiguous use of 'fun1()'
let stringResult2: String? = try? myClass.fun1() // ""

, , fun1 , Any, , Int String, , , Any, , Any, , , , .

+3

Source: https://habr.com/ru/post/1692548/


All Articles