2014-11-27 11:36:51 u013736404 阅读数 559
// Playground - noun: a place where people can play

import UIKit

//结构体&类的使用
struct NewStruct {
    var name:String = "";
    var age:Int = 18;
}

class Person{
    var person:NewStruct = NewStruct(name: "MichaelZero", age: 20);
    
    var className:String?;
    
    var friendIds:[Int]?;
    
    init(className:String){
        self.className = className;
    }
}

var person0 = Person(className:"C1");
println("PName:\(person0.person.name)");

//如果能够判定两个常量或者变量是否引用同一个类实例将会很有帮助。为了达到这个目的,Swift 内建了两个恒等运算符

var person1 = person0;
if person0 === person1{
    println("this is a same class.");
}else{
    println("this is a not same class.");
}

//结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。当你在考虑一个工程项目的数据构造和功能的时候,你需要决定每个数据构造是定义成类还是结构体。

//结构体的主要目的是用来封装少量相关简单数据值。
//有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用。
//任何在结构体中储存的值类型属性,也将会被拷贝,而不是被引用。
//结构体不需要去继承另一个已存在类型的属性或者行为。

//合适的结构体候选者包括:
//几何形状的大小,封装一个width属性和height属性,两者均为Double类型。
//一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。
//三维坐标系内一点,封装x,y和z属性,三者均为Double类型。

struct StaticStr {
    var name:Int;
    let systemName:String;
}

//除存储属性外,类、结构体和枚举可以定义计算属性,计算属性不直接存储值,而是提供一个 getter 来获取值,一个可选的 setter 来间接设置其他属性或变量的值。
class ParamsCount{
    var x:Int = 10;
    var y:Int = 10;
    var (x0, y0):(Int, Int);
    
    init(){
        (x0, y0) = (0 , 0);
    }
    
    var pointLink:(Int , Int){
        get {
            let x_link = self.x - self.x0;
            let y_link = self.y - self.y0;
            
            return (x_link , y_link);
        }
        
        set(newPoint){
            self.x = newPoint.0;
            self.y = newPoint.1;
        }
    }
}

//计算中心点坐标
struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
    size: Size(width: 10.0, height: 10.0));
let initialSquareCenter = square.center;
square.center = Point(x: 15.0, y: 15.0)
println("square.origin is now at (\(square.origin.x), \(square.origin.y))");


//结构体和枚举是值类型。一般情况下,值类型的属性不能在它的实例方法中被修改。
//但是,如果你确实需要在某个具体的方法中修改结构体或者枚举的属性,你可以选择变异(mutating)这个方法,然后方法就可以从方法内部改变它的属性;并且它做的任何改变在方法结束时还会保留在原始结构中。方法还可以给它隐含的self属性赋值一个全新的实例,这个新实例在方法结束后将替换原来的实例。
struct PointS {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = PointS(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
println("The point is now at (\(somePoint.x), \(somePoint.y))");

struct PointN {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        self = PointN(x: x + deltaX, y: y + deltaY)
    }
}

//实例方法是被类型的某个实例调用的方法。你也可以定义类型本身调用的方法,这种方法就叫做类型方法。声明类的类型方法,在方法的func关键字之前加上关键字class;声明结构体和枚举的类型方法,在方法的func关键字之前加上关键字static。
struct LevelTracker {
    static var highestUnlockedLevel = 1
    static func unlockLevel(level: Int) {
        if level > highestUnlockedLevel { highestUnlockedLevel = level }
    }
    static func levelIsUnlocked(level: Int) -> Bool {
        return level <= highestUnlockedLevel
    }
    var currentLevel = 1
    mutating func advanceToLevel(level: Int) -> Bool {
        if LevelTracker.levelIsUnlocked(level) {
            currentLevel = level
            return true
        } else {
            return false
        }
    }
}

class Player{
    var tracker = LevelTracker();
    let playerName : String;
    func completedLevel(level:Int){
        LevelTracker.unlockLevel(level+1);
        tracker.advanceToLevel(level+1);
    }
    
    init(name:String){
        playerName = name;
    }
}

var player = Player(name: "Zero");
player.completedLevel(1);
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)");

player = Player(name: "Michael")
if player.tracker.advanceToLevel(6) {
    println("player is now on level 6");
} else {
    println("level 6 has not yet been unlocked");
}

//下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值。语法类似于实例方法和计算型属性的混合。与定义实例方法类似,定义下标脚本使用subscript关键字,显式声明入参(一个或多个)和返回类型。
//这种是用于基于一个固定的数学公式
struct Times{
    let basicNum:Int;
    
    subscript(index:Int) -> String{
        return String.convertFromStringInterpolationSegment(index * basicNum);
    }
}

var times = Times(basicNum: 10);
println("testing Value\(times[5])");

//根据使用场景不同下标脚本也具有不同的含义。通常下标脚本是用来访问集合(collection),列表(list)或序列(sequence)中元素的快捷方式。你可以在你自己特定的类或结构体中自由的实现下标脚本来提供合适的功能。
struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(count: rows * columns, repeatedValue: 0.0)
    }
    func indexIsValidForRow(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValidForRow(row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}

var matrix = Matrix(rows: 10, columns: 10);

matrix[0 , 0] = 10;

println("value\(matrix[0 , 0])");

2016-07-05 10:35:31 CodingFire 阅读数 428

随着苹果又一届WWDC落幕,Swift又有了新的进展。博主也一直在考虑要不要学习Swift,就在前几天,博主无意间看到了一组图,找了下没找到,没发发出来给大家共享,大致内容是:
图中罗永浩问一个程序员:信不信你明天就要用Swift来开发?
程序员:不信。
罗永浩:苹果爸爸说从明天开始不使用Swift开发的App禁止上传到App Store。
程序员:。。。。。。
(以上纯属恶搞)
虽然苹果爸爸不会这么来干,但是也间接说明了Swift的主流性会越来越强,于是乎,博主感觉到了危机,仿佛看到了Object-C开发者的末日,再加上近年来的行情,不用博主多说,大家都会多多少少感觉到紧迫感吧,所以博主从今天开始入Swift的坑,推荐一个网址:http://www.runoob.com/swift(这网址跟博主半毛钱关系没有,不存在宣传,就是觉得基础内容很好),关于这里的内容,博主会把主要的东西和不是很理解的东西发在博客上,欢迎大家访问学习。

2016-09-03 17:56:41 yangyi2083334 阅读数 903

swift 5. 数组

标签:swift


妈蛋,真不容易啊,终于要说集合了。哎╮(╯▽╰)╭。这进度太慢了啊!

swift中的集合分好几种,他们统统成为集合类型。还是PHP大发好啊,一个数组类型就搞定所有。

按照可以是否存在相同类型的数据,具体分为,以下:

  • 数组 Arrays
  • 字典 Dictionaries

数组 Arrays

swift中的数组跟java和c 一样,只能包含相同类型的成员数据,要么全是整型,要么全是字符串,不能几种不同的类型混在一块,要是你想混在一起就得用object-c语言里面的的NSArray类型,最后会说到。

0. 申明一个数组

如何申明一个数组呢,和javascript是一样的,用[]表示。但是,我们要申明这个数组是要有变量类型的。所以,要用[类型]来标记。

//先申明
var array1:[String]

//后赋值
array1 = ["ab","cb","ed"]

print(array1) // 打印:[ab, cb, ed]

或者是申明和赋值连着一起来:

//申明赋值一起来
var array2:[Int] = [1,2,3,4,5,6]

print(array2)

上面2种方法都是先申明,后赋值了。swift中还有一种申明数组的方式,是申明一个空数组,或者叫先申明一个数组,给它附上空值。因为一个数组光申明,如果不初始化赋值,打印它是会报错。

var array6 = [Int]() //申明Int类型数组并初始化赋值为空
var array8 = [String]() //申明String类型数组并初始化赋值为空
print(array6)

我们也可以在申明一个数组后,给它设定默认的值:
var array = [type](count: count, repeatedValue:"value")
type 表示填充的变量类型。count 表示数组大小,repeatedValue 表示填充的值是什么。

var threeString = [String](count: 3, repeatedValue:"hello")
var threeInt= [Int](count: 3, repeatedValue:8)

print(threeString) // [hello, hello, hello]
print(threeInt) // [8, 8, 8]

或者直接去掉变量类型,swift会自动判断的:
var array = Array(count: count, repeatedValue:"value")

var threeString = Array(count: 3, repeatedValue:"hello")

print(threeString) // [hello, hello, hello]

之前我们就说过,swift中的变量的类型,我们是可以省略的,就像javascript的写法一样所以,swift会自动识别它的类型,所以一般我们会这样来表示一个数组:

var array3 = [1,2,3,4,5]
var array4 = ["a","b","c","d"]
var array5 = ["0",1,"ere"]

//输出
print(array3)
print(array4)
print(array5)

//屏幕输出结果
[1, 2, 3, 4, 5]
[a, b, c, d]
[1, 2, 3, "2111"]

注意
我们看到array5中居然是不同的数据类型成员,但是,编辑器没报错?你不是说swift中的数组是严格要求类型的吗?会报错吗?怎么这个是好的,还输出了。

因为,我们采用的是省略的写法,它就自动识别成[NSObject]类型了。所以也是正确的。最好不要用这种用法。

其他语言中是怎么申明和赋值数组的呢?

先是java, 哎,Java的一切都是蛋疼的,因为它推崇一切都是对象,所以,数组也是对象,也要new 初始化。

/*
    java
*/

//1 先申明,再new
String array1[];
array1 = new String[3];
//只能一个一个赋值
array1[0]= "ww";
array1[1]= "ww";
array1[2]= "ww";
//array1[3]= "ww"; //因为只申明了3个值,这个就溢出了,报错。蛋疼!

// 2. 一起
String array2[] = new String[3];
//只能一个一个赋值
array2[0]= "ww";
array2[1]= "ww";
array2[2]= "ww";

//第二种方式, 一步到位,并赋值
String array3[] = {"ww","fg","ere"};
//这个时候只能修改原来的值了,不能新增值,因为只有3个
array3[0] = 123; // 不匹配,报错,只能是字符串
array3[3] = "erd"; // 溢出了,报错!


for (String i:array3) {
    System.out.println(i);
}

php中当然是最爽的啦。随意使用!真是太爽了。

$a = []; //当然这一句也可以不要, 也不会错
$a = [
    1,2,3,"wohahah",5,"xixii"
];
$a[55] = "566";

javascript中,和swift很像

var array1[]; //申明一下。
array1= [1,2,3,4,5];//赋值
array1[0] = 9; //修改

1. 求数组大小

swift中也是用count来求数组大小,但是它是个数组的一个属性值,不是一个函数方法。

var array8 = [1,2,3,4,5,6,7,8,9];

var array_8_count = array8.count;

print("array8数组的大小为:\(array_8_count)")
//输出: array8数组的大小为:9

2. 判断数组是否为空

用属性isEmpty 来判断,它返回一个boolean值,true或false

if array8.isEmpty {
    print("The array8  is empty.")
} else {
    print("The array8  is not empty.")
}

3. 访问和修改数组成员

上面我们申明了很多数组,我们想要访问里面的某一个成员,比如访问第N个的值,我们可以和其他语言一样,用array[N]来访问的。

var shoppingList = ["Eggs", "Milk"]
var index_0 = shoppingList[0];
var index_1 = shoppingList[1];

print(index_0); //输出Eggs
print(index_1); //输出Milk

既然我们可以通过array[0]这样的方式取到第0个值,我们也同样可以用array[0] = "Pig"这样的方式,给第0个成员重新赋值,因为这个数组申明的为var变量,是可以重新修改赋值的,注意 如果是申明为let常量就不能这样改动了

var shoppingList = ["Eggs", "Milk"]

shoppingList[0] = "Pig" //将第0个元素重新赋值位Pig
shoppingList[1] = "Dog" //将第1个元素重新赋值位Dog

var index_0 = shoppingList[0];
var index_1 = shoppingList[1];

print(index_0); //Pig
print(index_1); //Dog

注意
下面会出现一个问题,也是极其容易想当然出错的。上面我们申明shoppList数组长度为2,那么它就限定死了。它的长度为2了。如果你通过array[2] = "hello"这种方式给它加上第3个成员,是会报错fatal error: Array index out of range

var shoppingList = ["Eggs", "Milk"]
shoppingList[2] = "Hello" //报错:fatal error: Array index out of range

那,难道我们就不能给一个预先定义的数组扩充吗?当然可以。看下面:

使用区间来修改数组

var oneToFive = [1,2,3,4,5] 

oneToFive[0...2] = [6,7,8]  // 0-2的索引值变成6.7.8
print(oneToFive) // [6,7,8,4,5]

oneToFive[0..<3] = [9] // 把 0-2的全变成9
print(oneToFive) // [9, 4, 5]

4. 向数组后追加新的成员

上面我们看到了,强行给数组添加新的成员是会报错的,那如何向数组后面追加新的成员呢?swift里也有这样一个方法函数append(),它是一个数组对象的一个方法,可以向这个数组后添加成员。

var animals = ["pig", "dog", "cat"]

animals.append("monkey")

print(animals) //输出:[pig, dog, cat, monkey]
print(animals[3]) // 输出:monkey

5. 向里数组任意某个索引值之前添加数据

append()方法是向数组的最后面追加数据,感觉比较鸡肋,不灵活,swift中的一个方法insert("value", atIndex: index)就非常灵活了。可以往任意索引前追加数据,记住,是往前。注意 : 后面的atIndex一定要写,不能省略。

var foods = ["egg","bread","rice"]
//往第0个索引,也就是egg,前面添加icecream。
foods.insert("icecream", atIndex:0)
//往第一个索引,注意,这时候,egg就变成第1个数据了。
foods.insert("humbeag", atIndex:1)

print(foods)
//打印:[icecream, humbeag, egg, bread, rice]

那么,既然有向前某个索引值钱追加,有往某个索引值后面追加的函数吗?对不起!没有。啊。你会觉得苹果很操蛋啊。其实不是。insert("value", atIndex:index)这个函数是往前追加,按照相对论的定义,不也是在往index-1的后面在追加数据吗?

var foods = ["egg","bread","rice"]

//我想往第1个索引值,也就是bread后面追加banana, 其实,也就是在rice,index=2前面追加了,对不对。
foods.insert("banana", atIndex: 2)

println(foods) //输出:[egg, bread, banana, rice]

7. 获取数组的第一个元素和最后一个元素

获取第一个元素和最后一个元素,返回的是可选型


var vowels: [Int] = [1,2,3,4,5]

print(vowels.first) // Optional(1)
print(vowels.last) // Optional(5)

//因为是可选型,所以用if let解包下
if let firstVowel = vowels.first{
    print("The first vowel is " , firstVowel) // The first vowel is  1
}

//强型解包
print(vowels.first!) // 1

vowels[vowels.count-1] // 5

8. 最大值、最小值

获取最小,最大值,返回的也是可选型

vowels.minElement() // Optional(1)
vowels.maxElement() // Optional(5)

9. 获取数组区间内的值

获取使用一个区间内的值。

vowels[1...2] // 从第2个-第3个的值: [2, 3]
vowels[1..<2] // 从第2个-第3个的值,不包含3 : [2]

vowels[1...vowels.count - 1] //取出 第 2个到最后一个的值: [2,3,4,5]

10. 数组包含

一个数组内是否包含一个值:Array.contains[n]。返回truefalse

 vowels.contains(1) // true
 vowels.contains(33) // false

let letter = 2
if vowels.contains( letter ){
    print("\(letter) is a vowel") // 输出这句
}
else{
    print("\(letter) is not a vowel")
}

查看一个元素在一个数组中的索引位置:Array.indexOf[n]。 返回的是可选类型。

var vv1 = vowels.indexOf(1) //1这个元素在0的索引上。
print(vv1) // Optional(0)

var vv2 = vowels.indexOf(8) //没有8这个元素,返回nil
print(vv2) // nil

11. 合并数组

可以用+=操作符号,来扩充数组,或者合并几个数组。arrray1+=[“value1”,”value2”] ,必须是相同类型的数据。

var mobile = ["iphone","htc","moto"]

mobile+=["huawei","lenove",]
mobile+=[4565] //类型不相同,报错。

var mobile2 = ["nokia"]
mobile += mobile2
//拆开也可以
var mobile3 = mobile + mobile2

print(mobile3)
// 输出:[iphone, htc, moto, huawei, lenove, 'nokia']

12. 删除某个索引值的数据

删除某个索引的值,可以用removeAtIndex(index)来移除,返回值是移除的这一项的值。

var mobile3 = ["iphone","htc","moto", "nokia"]
var who = mobile3.removeAtIndex(3)
print(who) // 打印:nokia
print(mobile3) // 打印:[iphone, htc, moto] nokia被移除了。

删除第一项和最后一项,可以用removeFirst()removeLast(),返回的是移除的这一项的值。

var mobile3: [String] = ["iphone","htc","moto", "nokia"]
var who1 = mobile3.removeFirst()
print(who1) // 打印:iphone

var who2 = mobile3.removeLast()
print(who2) // 打印:nokia

print(mobile3) // 打印:["htc","moto"] iphone, nokia被移除了。

删除所有,用:removeAll() 。它返回删除的值。

var mobile3: [String] = ["iphone","htc","moto", "nokia"]
mobile3.removeAll()

删除一个区间:removeRange(1...3) ,没返回值。

var mobile3: [String] = ["iphone","htc","moto", "nokia"]
mobile3.removeRange(1..<2) //删除了 htc
mobile3.removeRange(1...2) //删除了  htc 和 moto

13. 遍历数组

遍历数组,我们直接用for语句循环。以后将for会着重说:

for i in shoppingList {
    print(i)
}
//输出:
Pig
Dog
hello

或者我们想吧索引值也给循环出来,得用到枚举了。以后也会说到:

for (index, value) in enumerate(shoppingList) {
    print("Item \(index): \(value)")
}
//输出
Item 0: Pig
Item 1: Dog
Item 2: hello

14. 数组比较

swift中数组比较用==。它比较的的是值,和其它语言不一样。所以,比较2个数组,只要值是一摸一样就会相等。

var oneToFive = [1,2,3,4,5]
var numbers = [1,2,3,4,5]
numbers == oneToFive // true

//顺序变化就不想等了
var oneToFive2 = [1,2,4,3,5] 
numbers == oneToFive2 //false

15. 二维数组

//二维数组的声明
var board = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
//var board:[[Int]] = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
//var board:[Array<Int>] = = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
//var board:Array<[Int]> = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]
//var board:Array<Array<Int>> = [ [1024,16,2,0] , [256,4,2,0] , [64,2,0,0] , [2,0,0,0] ]


// 二维数组获取元素
board[0]
board[0][0]


// 获取二维数组两个维度的信息
board.count
board[0].count


// Swift中的二维数组,每一维度的元素数目可以不同
board[0].append(0)
board


// 为二维数组的第一个维度添加的元素是一个数组
board.append([0,0,0,0])
board += [ [0,0,0,0] ]
board

NSArray

NSArray数组是swift的前任objective-c里的声明数组的方式,在swift也被沿用了过来。简单说下,怎么使用,用的不多了。

//默认这样声明,不加类型,就是声明一个 NSArray
var Narray1 = []

// 用as 关键字转换
var Narray2 = [1,2,3,4,5] as NSArray

//显示的声明
var Narray3: NSArray = [1,"hello"]

var Narray4: [NSObject] = [1,"hello"]

好了。数组也说到这了。妈的。太不容易了。

2018-09-27 11:57:59 wenxin2526 阅读数 132

  Swift是苹果于2014年WWDC(苹果开发者大会)上发布的新的开发语言。可与Objective-C共同运行于Mac OS和iOS平台上,用于搭建基于苹果平台的应用程序。(由于Swift是开源的,所以Swift不仅仅可以编写Mac OS和iOS应用,还可以编写例如server端应用,后续会有相关介绍)

  发布会上用了四个词介绍Swift

  Fast—拥有比OC更快的速度

  Modern—支持Closures、Generics、Type inference、Multiple return types、Namespaces、Tuples等等

  Safe—Swift的设计以安全为出发点,以避免各种常见的编程错误

  Interactive—更优秀的可交互性,例如Playground

 Swift和OC一样支持Cocoa和Cocoa Touch,使用LLVM编译器,使用同样的优化程序和自动向量化器,ARC模式的内存管理,同时拥有和OC一样的runtime。

  虽然受到OC和其他语言的启发,但Swift本身并不是C的派生语言。作为一门完整且独立的语言,Swift将流控制、数据结构和函数等核心功能与对象,协议,闭包和泛型等高级结构打包在一起。

 Swift可与OC、C混编。Swift目前版本为4.x。

 Swift是一门具有与脚本语言同样的表现力和趣味性的系统编程语言。

 Swift完全开源。github地址https://github.com/apple/swift,社区地址https://swift.org/

  接下来我会系统的介绍Swift相关,从基本语法到最后拥有开发复杂应用的能力(中间还会穿插一些开发必备的技能,如设计模式等)。让我们一起踏上Swift之旅吧!!!

2015-07-07 11:49:01 soindy 阅读数 3037

     Swift的nil和OC中的nil不一样.在OC中,nil是一个指向不存在对象的指针.而在Swift中,nil不是指针,它是一个不确定的值.用来表示值缺失.任何类型的optional都可以被设置为nil.而在OC中,基本数据类型和结构体是不能被设置为nil的.




   给optional的常量或者变量赋值为nil.来表示他们的值缺失情况.一个optional常量或者变量如果在初始化的时候没有被赋值,他们自动会设置成nil.

swift初探

阅读数 168

Swift数值运算

阅读数 1516

Swift入门

阅读数 310

Swift学习笔记系列——(5)函数

博文 来自: erwin2012

swift学习

阅读数 1026

没有更多推荐了,返回首页