2017-07-19 5 views
0

Je suis en train de convertir Data bytes-sockaddr pour obtenir sa_family_toctets de données à SOCKADDR conversion Swift 3.1

En ObjC, il est comme ci-dessous:

NSData *  hostAddress; 
- (sa_family_t)hostAddressFamily { 
    sa_family_t  result; 

    result = AF_UNSPEC; 
    if ((self.hostAddress != nil) && (self.hostAddress.length >= sizeof(struct sockaddr))) { 
     result = ((const struct sockaddr *) self.hostAddress.bytes)->sa_family; 
    } 
    return result; 
} 

En rapide, je suis en train de le convertir comme ci-dessous:

var hostAddress:Data? 

private func hostAddressFamily() -> sa_family_t{ 

     var result: sa_family_t = sa_family_t(AF_UNSPEC) 
     if (hostAddress != nil) && ((hostAddress?.count ?? 0) >= MemoryLayout<sockaddr>.size) { 

      // Generic parameter 'ContentType' could not be inferred 
      self.hostAddress!.withUnsafeBytes({ bytes in 
       bytes.withMemoryRebound(to: sockaddr.self, capacity: 1, {sockBytes in 
        result = sockBytes.pointee.sa_family 
       }) 
      }) 
     } 

     return result 
    } 

Getting error : Generic parameter ‘ContentType’ could not be inferred

Répondre

0

Regardez la signature Data.withUnsafeBytesType:

func withUnsafeBytes<ResultType, ContentType>(_ body: (Swift.UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType 

Cette méthode est générique sur ResultType et ContentType et le ContentType est utilisé dans l'argument du corps de fermeture.

Ce que le compilateur essaie de dire est qu'il ne sait pas de quel type est bytes. En général, pour corriger ce type d'erreurs, vous souhaitez annoter le type dans la fermeture:

data.withUnsafeBytes { (_ bytes: UnsafePointer<...>) -> Void in ... } 

Aussi, il est peu probable que vous aurez besoin de lier la mémoire deux fois depuis NSData est typées, et vous avez déjà spécifier un type auquel le lier.


Mettre le tout ensemble:

func hostAddressFamily() -> sa_family_t { 

    var result = sa_family_t(AF_UNSPEC) 

    guard 
    let hostAddress = hostAddress, 
    hostAddress.count >= MemoryLayout<sockaddr>.size 
    else { 
    return result 
    } 

    hostAddress.withUnsafeBytes { (_ bytes: UnsafePointer<sockaddr>) in 
    result = bytes.pointee.sa_family 
    } 

    return result 
}