2016-01-09 27 views

cevap

3

sizin koduyla aynı etkiye sahip tek anlatım

funcThatReturnsOptional().map { object.nonOptionalProperty = $0 } 

ama kod kesinlikle daha iyi okunabilir.

İşte Optional ait map() yöntemi kullanılırsa ve kapatma fonksiyonu nil dönmez taktirde uygulanabilecek olduğunu. isteğe varsa aslında isteğe bağlı olmayan bir isteğe bağlı atayabilirsiniz Yukarıdaki olarak tanımlanan ?= kullanarak

infix operator ?= { associativity right precedence 90 } 
func ?= <T: Any> (inout left: T, right: T?) { 
    if let right = right { 
     left = right 
    } 
} 

:

+0

peki tamam bu aslında bir satırdır ama gerçekten korkunç görünüyor: D daha iyi okunabilir bir çözüm olduğunu düşündüm (belki bir şey ??? operatör ile) – Ch1llb4y

+2

@ Ch1llb4y: Böyle bir çözüm bilmiyorum. Özel bir görev operatörü tanımlayabilirsiniz. Sorun, operatör işlevinde yeni bir değer atamasanız bile giriş parametrelerinin özellik dizisini tetiklemesidir. –

2

Tamam, aslında yeni bir operatöre ?= tanıtarak tam bunu başarmak için bir yol var İçinde bir değer.

kullanılması çok hantal olmayan çeşitli yolları vardır

+0

Evet, ancak bir değişkenin "myVar? = Nil" değerinde operatöre geçirilmesinin, özellik gözlemcileri willSet/didSet'i çağırdığını ve her ikisini de kullanmasanız bile hesaplanmış özellik durumunda olsun/ayarlayacağınızı unutmayın. t Operatörün içine yeni bir değer atayın. –

+0

@MartinR iyi, ama en azından ifadeyi kısaltır. – Ch1llb4y

2

vardır ?? : Bir uzantı kullanarak

infix operator <-?? { associativity right precedence 90 assignment } 
func <-??<T>(inout variable:T, value:T?) 
{ if value != nil { variable = value! } } 

object.nonOptionalProperty <-?? funcThatReturnsOptional() 

: bir operatör kullanarak

func setNotNil<T>(inout variable:T, _ value:T?) 
{ if value != nil { variable = value! } } 

setNotNil(&object.nonOptionalProperty, funcThatReturnsOptional()) 

:

object.nonOptionalProperty = funcThatReturnsOptional() ?? object.nonOptionalProperty 

bir fonksiyonunu kullanarak

extension Equatable 
{ mutating func setNotNil(value:Self?) { if value != nil { self = value! } } } 

object.nonOptionalProperty.setNotNil(funcThatReturnsOptional()) 
+0

Bunların hepsi, eski değer yeniden atanırken, 'nonOptionalProperty' ayarlayıcısını tetikler. – Ch1llb4y

+0

İşlev uygulamasını değiştirdim, ancak bununla ilgili endişeleriniz zincir isteğe bağlı olarak atanıyorsa, lütfen bu soruya verdiğim yanıtlara bakın: http://stackoverflow.com/questions/34838661/crash-on-unwrapping-nil-optional/34867082 # 34867082 –

1

ne @ ch1llb4y ne de sağlanan çözüm @ tyler-sheaffer, jeneriklerden beri çalışıyor İsteğe bağlı değerler hakkında bilgi kaybeder. Ancak bu, aşağıdaki unwrap yöntemini kullanarak düzeltilebilir.

precedencegroup OptionalAssignment { 
    associativity: right 
} 

infix operator ?= : OptionalAssignment 

public func ?= <T>(variable: inout T, value: T?) { 
    if let unwrapped = unwrap(any: value) ?? nil { 
     variable = unwrapped 
    } 
} 

public func unwrap<T: Any>(any: T) -> T? { 
    let mirror = Mirror(reflecting: any) 
    guard mirror.displayStyle == .optional else { return any } 
    guard let child = mirror.children.first else { return nil } 
    return unwrap(any: child.value) as? T 
} 

Henüz olsa unwrap(any: value) ?? nil yılında ?? nil yazmak zorunda değil bir çözüm gelmedik.

İlgili konular