Objective-C和C语言常常须要使用到指针。Swift中的数据类型因为良好的设计,使其能够和基于指针的C语言API无缝混用。同时Swift也能够自动处理大多数将指针做为参数的状况。在这篇文章里,咱们能够看到在Swift语言中如何将变量、数组、字符串当作C语言中的指针参数来使用。swift
C和Objective-C不支持多类型的返回值。因此Cocoa API就使用指针做为函数的输入输出参数,以用来传递多类型的数据。Swift容许使用指针参数进行相似inout
参数的处理,因此你可使用&
语法将一个var
变量的引用做为指针参数进行传递。好比说,UIColor
的getRed(_:green:blue:alpha:)
方法,使用4个CGFloat*
指针用来接收颜色的组成元素。咱们可使用&
将这几个颜色组成部分装配在本地变量中。数组
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0 color.getRed(&r, green: &g, blue: &b, alpha: &a)
另一个常见的状况出如今Cocoa NSError
类的使用中。不少方法都使用一个NSError**
参数来保存异常信息。好比说,咱们能够经过NSFileManager
类的contentsOfDirectoryAtPath(_:error:)
方法,挪列出指定目录中的信息,一旦出现疑似异常信息,就将其保存在NSError?
类型的变量中。安全
var maybeError: NSError? if let contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/usr/bin", error: &maybeError) { // Work with the directory contents } else if let error = maybeError { // Handle the error }
为安全起见,Swift要求在使用&
传值时,变量必须是已经被初始化的。这是由于Swift没法知道也没法判断在操做指针以前,该指针是否确实在内存有指向的地址。框架
在C语言中,指针与数组是水乳交融,纠缠不清的。那么为了在Swift中能无缝的使用C语言中基于数组的一些API,Swift容许将Array
做为指针参数。一个不可变数组的值能够做为一个const
指针参数直接传递,可变数组可使用&
做为一个非const
指针参数进行传递,就inout
参数同样。好比,咱们使用Accelerate
框架中的vDSP_vadd
函数对数组a
和数组b
进行相加,将结果写入result
数组:函数
import Accelerate let a: [Float] = [1, 2, 3, 4] let b: [Float] = [0.5, 0.25, 0.125, 0.0625] var result: [Float] = [0, 0, 0, 0] vDSP_vadd(a, 1, b, 1, &result, 1, 4) // result now contains [1.5, 2.25, 3.125, 4.0625]
C语言中,传递字符串的主要方式是经过const char*
指针。在Swift中,String
也能够被用做const char*
指针,用它能够向函数传递空字符串或UTF-8编码的字符串。好比,咱们能够在标准的C语言和POSIX的库函数中直接使用字符串做为参数传递:编码
puts("Hello from libc") let fd = open("/tmp/scratch.txt", O_WRONLY|O_CREAT, 0o666) if fd < 0 { perror("could not open /tmp/scratch.txt") } else { let text = "Hello World" write(fd, text, strlen(text)) close(fd) }
Swift一直在努力让咱们能够方便的、无缝的使用C语言中的指针,由于在Cocoa中已经使用的很是广泛了。虽然Swift是一个类型安全的语言,对指针参数的转换的安全性也有保障,可是相比Swift原生的其余代码来讲,仍是存在着必定的不安全性。因此咱们在使用时要格外当心。好比说:设计
若是你使用的基于指针的API不在这篇指导内,或者你须要重写接收指针参数的Cocoa方法,那么你能够直接使用Swift原始内存中的不安全的指针。咱们会在之后的文章中介绍更多Swift的特性。指针
本文首发地址:在Swift中使用C语言的指针code