2016年5月30日星期一

Swift中指针使用及操作

在Swift中指针用两个特殊的类型来描述,UnsafePointer和UnsafeMutablePointer,遵循Cocoa的原则,可以看出不可变可变的不同,当创建指针之后,可以通过指针的memory来操作指针。另外,Swift中UnsafeBufferPointer用来描述一组连续的数据指针,COpaquePointer用来描述非完整结构的不透明指针。
在函数中传递指针(指针作为函数参数进行传递)
在函数中传递指针有两种方式,一:使用inout关键字。二:使用Swift准备的指针类型。
使用inout关键字:
var num:Int = 10
func some(inout numb:Int){
    //如果使用inout关键字,在函数体内部不需要处理指针类型,可直接操作
    numb += 1
    print("numb --> \(numb)")
}
some(&num)
print("num ---> \(num)")
使用Swift准备的指针类型
var num:Int = 10
func some(numb:UnsafeMutablePointer<Int>){
    //如果使用Swift提供的类型,那么需要使用memory来进行操作
    numb.memory += 1
    print("numb --> \(numb.memory)")
}
some(&num)
print("num ---> \(num)")
需要注意的是,Swift中地址符&是不能直接使用的,只能是函数传递时才可用。
如何直接操作
虽然无法像OC或者C中那样直接通过地址符&来操作指针,但是Swift也提供了辅助的方法间接的来帮助我们来操作指针。
var i:Int = 10
i = withUnsafeMutablePointer(&i, {
   (p:UnsafeMutablePointer<Int>) -> Int in
       p.memory += 20
       return p.memory
})
print("i value ---> \(i)")
如何使用指向数组的指针
如果只是函数传递,不可变直接传递,可变使用&符即可,如果想直接操作,那么还是需要UnsafeBufferPointer来辅助完成。
var array:[Int] = [2,1,3,4]
var arrayPtr:UnsafeMutableBufferPointer<Int> = UnsafeMutableBufferPointer<Int>(start: &array, count: array.count)
var baseArrayPtr:UnsafeMutablePointer<Int> = arrayPtr.baseAddress as UnsafeMutablePointer<Int>
var nextPtr:UnsafeMutablePointer<Int> = baseArrayPtr.successor()
var threPtr:UnsafeMutablePointer<Int> = nextPtr.successor()

print("第一个元素  \(baseArrayPtr.memory)")
print("第二个元素 \(nextPtr.memory)")
print("第三个元素  \(threPtr.memory)")
如何通过指针强制转换类型
这个操作比较危险,除非你明确预期知道类型,不然编译器是无法知道的,也就造成了非常大的不确定性。
let arr:NSArray = NSArray(object: "icepy")
let str:NSString = unsafeBitCast(arr[0],NSString.self)

print("str --- > \(str.stringByAppendingPathComponent("app"))")
创建一个指针
//创建可变指针
var i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)
i.initialize("icepy")
内存管理
还有一点要注意的是,如果是属于自己手动创建的指针,Swift是不负责管理内存的,需要手动的销毁与释放。
一个UnsafeMutablePointer内存一般有三个状态:
  • 内存没有被分配,null指针
  • 内存进行了分配,且值还未初始化
  • 内存进行了分配,且值已经初始化
var i:UnsafeMutablePointer<String> = UnsafeMutablePointer<String>.alloc(10)
i.initialize("icepy")        
print("i的内存地址 \(i)")
print("i的memory \(i.memory)")        
i.destroy() //销毁指针指向的对象
i.dealloc(10) //销毁指针申请的内存
i = nil

2016年5月8日星期日

Go Golang

        因为新版的Golang使用Go本身编译Golang,不再使用C编译器,所以需要先安装Go 1.4,否则在安装1.6版本时会报错ERROR: Cannot find /home/xxx/go1.4/bin/go。
         在.bash_profile文件中设置Go环境变量:
                  export GOROOT_BOOTSTRAP=$HOME/go1.4.3
                  export GOROOT=$HOME/go1.6.2
                  export GOPATH=$HOME/Go/Proj1:$HOME/Go/Proj2
                  export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
          Go compiler的package搜索顺序:首先在安装目录GOROOT查找,没有则继续GOPATH=PATH1:PATH2的PATH1/src/filename.go和PATH2/src/filename.go,如果均没有找到则提示错误。上述GOPATH中的PATH1和PATH2被称为workplace

          一般Go项目目录结构:
                                                  Proj1/
                                                           bin/
                                                           pkg/
                                                           src/
                                                                lib1/      
                                                                      lib1.go
                                                                lib2/     
                                                                      lib2.go
                                                                app/     
                                                                      main.go
                                                  Proj2/
                                                           bin/
                                                           pkg/
                                                           src/
                                                                lib1/      
                                                                      lib1.go
                                                                lib2/     
                                                                      lib2.go
                                                                app/     
                                                                      main.go