IOS开发-Swift-基础知识学习笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaolaoda2012/article/details/69943695

实例代码下载:
IOS开发-Swift-基础知识学习笔记

1.定义常量变量,显示指定类型

        var myVariable = 42;
        let myConstant = 42;
        //指定类型
        var myChange: Float = 4;
        myVariable = 50;
        myChange = 666;
        print("\(myVariable) \(myConstant) \(myChange)");

2.转换成字符串的方法

        let label = "the width is ";
        let width = 94;

        let widthLabel = label+String(width);
        print(widthLabel);

        let apple = 3;
        let orange = 5;
        let appleSummary = "i have \(apple) apples.";
        let orangeSummary = "i have \(orange+apple) pieces of fruit";

        print(appleSummary);
        print(orangeSummary);

        let name = "zhao";
        let times = 3.0;
        let ask = "say \(times) times hello to \(name)";
        print(ask);

3.创建数组和字典,创建空数组和空字典

        var shoppingList = ["catfish","water","tulips","blue paint"];
        shoppingList[1] = "bottle of water";

        var occupations = ["Malcolm":"Captain","Kaylee":"Mechanic"];
        occupations["Jayne"] = "Public Relations";

        print(shoppingList);
        print(occupations);

        let emptyDictionary = Dictionary<String,Float>();
        let emptyArray = [String]();
        shoppingList = [];
        occupations = [:];

        print(shoppingList);
        print(emptyDictionary);
        print(emptyArray);

4.控制流 if,switch,for-in,for,while,do-while

        let individualScores = [75,43,103,87,12];
        var teamScore = 0;
        for score in individualScores {
            if score>50{
                teamScore += 3;
            }
            else{
                teamScore += 1;
            }
        }
        print("team score : \(teamScore)");

swift的switch与很多语言不同,他是可以处理很多种类型的,比如String类型

        let vegetable = "red pepper";
        var vegetableComment = "";
        switch vegetable {
        case "celery":
            vegetableComment = "Add some raisins and make ants on a log.";
        case "cucumber","watercress":
            vegetableComment = "That would make a good tea sandwich.";
        case let x where x.hasSuffix("pepper"):
            vegetableComment = "Is it a spicy \(x)?";
        default:
            vegetableComment = "Everything tastes good in soup.";
        }
        print(vegetableComment);

比较神奇的就是,其他语言一般都要在case的末写上break,但是swift不同,运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break。

        let interestiongNumbers = [
            "Prime": [2, 3, 5, 7, 11, 13],
            "Fibonacci": [1, 1, 2, 3, 5, 8],
            "Square": [1, 4, 9, 16, 25],
        ];
        var largest = 0;
        for (kind,numbers) in interestiongNumbers {
            for number in numbers {
                if(number > largest){
                    largest = number;
                }
            }
        }
        print("largest \(largest)");

在for (kind,numbers) in interestiongNumbers 这一句代码会提示一个警告:
这里写图片描述
提示可以用 “_” 代替,因为这个kind在下面的代码中是没有用到的。
这个小下划线是有很多作用的,具体作用贴个链接:
swift下划线和”#”的妙用
使用”..”和”…”,来循环遍历:

        for i in 1..<10{
            print(i)
            // 打印结果为1-9
        }
        for i in 1...10{
            print(i)
            //打印结果为1-10
        }

do-while在swift是没有的,而是使用repeat-while来代替,do是用来异常捕获等。

        var n = 2;
        while n<100 {
            n = n*2;
        }
        print("while \(n)");

        var m = 2;
        repeat{
            m = m * 2;
        }while m<100
        print("do \(m)");

5.可选值 一个可选的值可能是一个具体的值或者是nil,表示值缺失。在类型后面加一个问号来标记这个变量的值是可选的

        var optionalString : String? = "hello";
        optionalString = nil;

        var optionalName : String? = "John Appleseed";

        var greeting = "hello!";

        if let name = optionalName{
            greeting = "hello,\(name)";
        }
        print(optionalString);
        print(optionalName);
        print(greeting);

在第三句代码会有一个警告:
这里写图片描述
variable ‘optionalName’ was never mutated;consider changing to ‘let’ constant
意思是这个变量,创建后,没有再发生变化,最好用let这个关键字去修饰,Swift的编译器可以对let进行优化,从而获得更好的性能。
在下面的三个print里面,前面两个也是会出现警告的:
这里写图片描述
swift会提供三个方法,解决这个警告,分别是:
(1)提供一个默认值来,避免这个警告

扫描二维码关注公众号,回复: 3219552 查看本文章
print(optionalString ?? "1111");

(2)使用强制解包,避免这个警告

print(optionalName!);

(3)显示转换成Any类型,避免这个警告

print(optionalString as Any);

6.函数和闭包
使用func来声明一个函数,使用名字和参数来调用函数。使用->来指定函数返回值。

    func greet(name:String,day:String) -> String {
        return "hello \(name),today is \(day)";
    }

    print(greet(name: "bob", day: "thuesday"));

使用一个元组来返回多个值。

    func getGasPrices()->(Double,Double,Double){
        return (3.59,3.639,3.79);
    }
    print(getGasPrices());

函数的参数数量是可变的

    //数组当参数1
    func sumOf(numbers:[Int]) -> Int {
        var sum = 0;
        for number in numbers {
            sum += number;
        }
        return sum;
    }
    //数组当参数2
    func sumOf(numbers:Int...) -> Int {
        var sum = 0;
        for number in numbers {
            sum += number;
        }
        return sum;
    }
    print(sumOf(numbers:[]));
    print(sumOf(numbers: [42,597,12]));
    print(sumOf());
    print(sumOf(numbers: [42,597,12]));

函数可以嵌套。被嵌套的函数可以访问外侧函数的变量,你可以使用嵌套函数来重构一个太长或者太复杂的函数。

    //函数嵌套
    func returnFifteen() -> Int {
        var y = 10;
        func add(){
            y+=5;
        }
        add();
        return y;
    }
    print(returnFifteen());

函数可以作为另一个函数的返回值

    //函数作为返回值
    func makeIncrementer() -> ((Int)->Int) {
        func addOne(number:Int)->Int{
            return 1+number;
        }
        return addOne;
    }
    let increment = makeIncrementer();
    print(increment(7));

函数也可以当做参数传入另一个函数

    //函数可以当做参数传入另一个函数
    func hasAnyMatches(list:[Int],condition:(Int)->Bool) -> Bool {
        for item in list {
            if condition(item) {
                return true;
            }
        }
        return false;
    }
    func lessThanTen(number:Int) -> Bool {
        return number<10;
    }
    let numbers = [20,19,7,12];
    print(hasAnyMatches(list: numbers,condition: lessThanTen));

    //函数实际上是一种特殊的闭包,你可以使用{}来创建一个匿名闭包。使用in来分割参数并返回类型。
    let res = numbers.map({
            (number:Int) -> Int in
            let result = 3*number;
            return result;
        })

    print(res);

7.类,对象,属性

class Square: NamedShape {
        var sideLength:Double;
        init(sideLenght:Double,name:String) {
            self.sideLength = sideLenght;
            //调用父类的init方法
            super.init(name: name);
            numberOfSides = 4;
        }

        func area() -> Double {
            return sideLength*sideLength;
        }

        //子类如果要重写父类的方法的话,需要用override标记——如果没有添加override就重写父类方法的话编译器会报错。编译器同样会检测override标记的方法是否确实在父类中
        override func simpleDescription() -> String {
            return "a square with sides of length \(sideLength).";
        }
    }

    class NamedShape {
        var numberOfSides:Int = 0;
        var name:String;

        //构造函数
        //注意self被用来区别实例变量。当你创建实例的时候,像传入函数参数一样给类传入构造器的参数。每个属性都需要赋值——无论是通过声明(就像numberOfSides)还是通过构造器(就像name)。
        init(name:String) {
            self.name = name;
        }
        func simpleDescription() -> String {
            return "a shape with \(numberOfSides) sides.";
        }

        //析构函数
        //如果你需要在删除对象之前进行一些清理工作,使用deinit创建一个析构函数。
        deinit {

        }
    }

    class Shape {
        var numberOfSides = 0;
        func simpleDescription() -> String {
            return "a shape with \(numberOfSides) sides";
        }
    }

        let shape = Shape();
        shape.numberOfSides = 7;
        let shapeDescription = shape.simpleDescription();
        print(shapeDescription);

        let square = Square(sideLenght: 5.2, name: "my test square");
        print(square.area());
        print(square.simpleDescription());
class EquilateralTriangle: NamedShape {
        var sideLength:Double = 0.0;
        init(sideLength:Double,name:String) {
            //设置子类声明的属性值
            self.sideLength = sideLength;
            //调用父类的构造器
            super.init(name: name);
            //改变父类定义的属性值。其他的工作比如调用方法、getters和setters也可以在这个阶段完成。
如果你不需要计算属性但是需要在设置一个新值之前运行一些代码,使用willSet和didSet。
            numberOfSides = 3;
        }
        //重写属性的get set 方法
        var perimeter :Double{
            get{
                return 3.0*sideLength;
            }
            set{
                sideLength = newValue/3.0;
            }
        }

        override func simpleDescription() -> String {
            return "an equilateral triangle with sides of length \(sideLength)";
        }
    }
    let triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle");
    print(triangle.perimeter);
    triangle.perimeter = 9.9;
    print(triangle.perimeter)
    print(triangle.sideLength);
    print(triangle.simpleDescription());

willSet和didSet,下面是让三角形和四边形的变长始终相等。

class TriangleAndSquare {
        var triangle:EquilateralTriangle {
            willSet{
                square.sideLength = newValue.sideLength;
            }
        }
        var square:Square {
            willSet{
                triangle.sideLength = newValue.sideLength;
            }
        }
        init(size:Double,name:String) {
            square = Square(sideLenght: size, name: name);
            triangle = EquilateralTriangle(sideLength: size, name: name);
        }
        print("-------------------");
        let triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape");
        print(triangleAndSquare.square.sideLength);
        print(triangleAndSquare.triangle.sideLength);
        triangleAndSquare.square = Square(sideLenght: 50, name: "larger square");
        print(triangleAndSquare.triangle.sideLength);
    }
class Counter {
        var count:Int = 0;
        func incrementBy(amount:Int,numberOfTimes times:Int) {
            //类中的方法和一般的函数有一个重要的区别,函数的参数名只在函数内部使用,但是方法的参数名需要在调用的时候显式说明(除了第一个参数)。默认情况下,方法的参数名和它在方法内部的名字一样,不过你也可以定义第二个名字,这个名字被用在方法内部。
            count += amount*times;
        }
    }

        let counter = Counter();
        counter.incrementBy(amount: 2, numberOfTimes: 7)
        print(counter.count);

8.枚举和结构体

enum Rank:Int {
        case Ace = 1
        case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
        case Jack, Queen, King
        func simpleDesciption() -> String {
            switch self {
            case .Ace:
                return "ace"
            case .Jack:
                return "jack"
            case .Queen:
                return "queen"
            case .King:
                return "king"
            default:
                return ""
            }
        }
    }

        print("-------------------");
        let ace = Rank.Ace;
        let aceRawValue = ace.simpleDesciption();
        print(aceRawValue);
        print(ace.rawValue);

enum ServerResponse {
        case Result(String,String)
        case Error(String)
    }
//        一个枚举成员的实例可以有实例值。相同枚举成员的实例可以有不同的值。创建实例的时候传入值即可。实例值和原始值是不同的:枚举成员的原始值对于所有实例都是相同的,而且你是在定义枚举的时候设置原始值。
        let success = ServerResponse.Result("6:00 am", "8:09 pm")
        let failure = ServerResponse.Error("out of cheese")
        switch failure {
        case let .Result(sunrise,sunset):
            let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)"
            print(serverResponse);
        case let .Error(error):
            let serverResponse = "Failure.. \(error)"
            print(serverResponse);
        }
//使用struct来创建一个结构体。结构体和类有很多相同的地方,比如方法和构造器。它们结构体之间最大的一个区别就是 结构体是传值,类是传引用。
    struct Card {
        var rank:Rank;
        func simpleDescription() -> String {
            return "the \(rank.simpleDesciption())";
        }
    }
        print("-------------------");
        let card = Card(rank: .Ace);
        let cardDesc = card.simpleDescription();
        print(cardDesc);

9.接口与扩展

///声明一个接口
protocol ExampleProtocol {
    var simpleDescription:String {get}
    mutating func adjust()
}

///类,枚举,结构体可以实现接口
class SimpleClass:ExampleProtocol{
    var simpleDescription: String = "a very simple class";
    var anotherProperty:Int = 69105
    func adjust() {
        simpleDescription += " now 100% adjusted"
    }
}

//mutating关键字用来标记一个会修改结构体的方法,SimpleClass的声明不需要标记任何方法因为类中的方法经常会修改类
struct SimpleStructure:ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += "(adjusted)"
    }
}

        print("-------------------");
        let a = SimpleClass();
        a.adjust();
        let aDesc = a.simpleDescription;
        print(aDesc)


        print("-------------------");
        var b = SimpleStructure();
        b.adjust();
        print(b.simpleDescription);

扩展的写法,一个Int的extension:

//使用extension来为现有的类型添加功能,比如添加一个计算属性的方法。你可以使用扩展来给任意类型添加协议,甚至是你从外部库或者框架中导入的类型。
extension Int:ExampleProtocol{
    var simpleDescription:String {
        return "the number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
        print("-------------------");
        print(3.simpleDescription);

//protocolValue变量运行时的类型是simpleClass,编译器会把它的类型当做ExampleProtocol。这表示你不能调用类在它实现的接口之外实现的方法或者属性。
        print("-------------------");
        let protocolVaule:ExampleProtocol = a;
        print(protocolVaule.simpleDescription);

10.泛型

//在尖括号里写一个名字来创建一个泛型函数或者类型。
    func repeatFunc<ItemType>(item:ItemType,times:Int) -> [ItemType] {
        var result = [ItemType]();
        for _ in 0...times {
            result += [item];
        }
        return result;
    }

        print("-------------------");
        print(repeatFunc(item: "knock", times: 4));
//创建泛型类、枚举和结构体。
    enum OptionalValue<T> {
        case None
        case Some(T)
    }

        print("-------------------");
        var possibleInteger:OptionalValue<Int> = OptionalValue.None;
        print(possibleInteger);
        possibleInteger = OptionalValue.Some(100);
        print(possibleInteger);

猜你喜欢

转载自blog.csdn.net/zhaolaoda2012/article/details/69943695