"I" cannot be used in nontrivial closures

I would like to have a class with a static initialization method:

class A {

  required init() {
  }

  // this one works
  class func f0() -> Self {
    return self.init()
  }

  // this one works as well      
  class func f1() -> Self {
    let create = { self.init() } // no error, inferred closure type is '() -> Self'
    return create()
  }
}

Unfortunately, the Swift 3 compiler cannot deduce a type for any closure more complicated than { self.init() }. For instance:

class func f2() -> Self {
  let create = {
    // error: unable to infer complex closure return type; add explicit type to disambiguate
    let a = self.init()
    return a
  }

  return create()
}

Any attempt to indicate the type of closure, the type of the variable explicitly or from Ato Selfresults in an error:

class func f3() -> Self {
  let create = { () -> Self in // error: 'Self' is only available in a protocol or as the result of a method in a class;
    let a = self.init()
    return a
  }

  return create()
}

class func f4() -> Self {
  let create = {
    let a: Self = self.init() // error: 'Self' is only available in a protocol or as the result of a method in a class;
    return a
  }

  return create()
}

class func f5() -> Self {
  let create = { () -> A in
    let a = self.init()
    return a
  }

  return create() as! Self // error: cannot convert return expression of type 'A' to return type 'Self'
}

The solution is to avoid short circuits with Self.

This seems like a very unsuccessful compiler restriction. Is there a reason for this? Perhaps this problem will be fixed in future versions of Swift?

+4
source share
1 answer

, Swift Self , . , Self, , Swift , ( , , , ).

, . ? , "" ? , , ? ( , .)

, , Swift ( , ) , Swift 4 5.

+2

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


All Articles