Dart的基本语法

变量

dart是脚本类语言,可以不预先定义变量类型 ,会自动类型推导。定义变量可以通过var关键字来声明变量
var后就不要写类型 ,写了类型不要var

ar str='this is var';
String str='this is var';
int str=123;

自动推断变量类型 var ;类型关键字不要和变量关键字一块使用;
dart里面有类型校验。例如定义了一个 String str = 'ewere'; 后面又写为 Str = 1234; 那么这样就会报错

常量

常量使用 const关键字来定义,一经定义不能修改 例如: const PI = 123;
final 关键词也可以来定义常量;区别就是final不仅有const的编译时常量的特性,
最重要的,它是个运行时常量,并且final是惰性初始化的,即在运行时第一次使用才初始化 fianl time = new DateTime.now();

final 和 const修饰符的区别

  1. const 一开始就得赋值
  2. final 可以开始不赋值,但只能赋一次 ;
    而final不仅有const的编译时常量的特性,最重要的它是运行时常量,并且final是惰性初始化,即在运行时第一次使用前才初始化

永远不改量的量,请使用final或const修饰它,而不是使用var或其他变量类型。

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

注释

第1种方式
//  

第2种方式
///  

第3种方式
/*
*/
  • 文件是.dart结尾
  • 每一句代码后面以 ; 号结尾
  • 字符串、数字类型的写法:
String  temp = '这是一个字符串';
int num = 1234;
  • 打印(打印对象时,括号里面没有引号)
   print(num);
   print('你好');
   print('$name');
   print('${this.name}');

常用数据类型:

  • int
  • double
  • String
  • bool
  • List(数组):在dart中,数组就是列表对象,一般称他们为列表
  • Maps(字典):Map是一个键值对相关的对象,键和值可以是任何类型的对象
  1. String类型

可以是单引号,也可以是双引号;

String  str1='hhhhh';
String  str2="ffff";

还可以使用3个单引号或者双引号定义多行文字

String  str3="""
1111111111
22222222
333333333
""";

字符串的拼接

String str1="2222";
String str2="333";
print(str1 + str2);
print(str1 + " " + str2);

字符串的原始字符

// 字符串前面加r;那么\n就不会当作换行符处理
var s = r'ffff  4444 \n iii  yyyy ';
  1. 数值类型

int 必须是整型
double 可以是整型也可以是浮点型

  1. 布尔类型
    只能有两个值 true false

  2. List类型

var array = ["aaa","bbb","ccc"];
print(array);
print(array.length);
print(array[1]);

另外一种创建方式

var arr=new List();

dynamic

List < dynamic > array = [1,'2'];

List里面常用的属性和方法:

  • 常用属性:
        length          长度
        reversed        翻转
        isEmpty         是否为空
        isNotEmpty      是否不为空
  • 常用方法:
        add         增加
        addAll      拼接数组
        indexOf     查找  传入具体值
        remove      删除  传入具体值
        removeAt    删除  传入索引值
        fillRange   修改   
        insert(index,value);            指定位置插入    
        insertAll(index,list)           指定位置插入List
        toList()    其他类型转换成List  
        join()      List转换成字符串
        split()     字符串转化成List
        forEach   
        map
        where
        any
        every
arr.add('你好'); //增加
arr.addAll(['hao','effdf']);  //拼接数组
arr.indexOf('dfdf'); //查找不到返回-1
remove //删除对象
removeAt //删除下标
fillRange(startIndex,endIndex,'要修改的内容');
insert('增加一个值');
insertAll(1,['11','222']); //指定位置插入List
arr.join('==='); //拼接数组为字符串
split()     //字符串转化成List
List myList =[1,2,3,4];
var newList = myList.map((value){   //map的用法:遍历修改List中的每一项的值
return value*2;
});

List array = [1,2,3,4,5,6,7];
var newArr = array.where((value){  //where:返回满足条件的数据
return value > 5;
});

List myList=[1,3,4,5,7,8,9];
var f=myList.every((value){   //每一个都满足条件返回true  否则返回false
return value>5;
      });
 print(f);

定义已知类型的List

var arr1=new List<String>();

API方法有 length isEmty isNotEmpty reversed

//字符串分割为数组
var  str3='www-eee-rrr-ttt';
str.split('-');
  1. Maps类型
var animal={
'name':'小狗',
'age':2
};
print(animal['age']);

另外一种定义方式

var a =new Map();
a['name']='小狗';
a['age']=20;
animal.keys

映射(Maps)是无序的键值对:

  • 常用属性:
 keys            获取所有的key值
 values          获取所有的value值
 isEmpty         是否为空
 isNotEmpty      是否不为空
  • 常用方法:
remove(key)     删除指定key的数据
addAll({...})   合并映射  给映射内增加属性
containsValue   查看映射内的值  返回true/false
forEach   
map
where
any
every
print(person.keys.toList());
print(person.values.toList());
print(person.isEmpty);
print(person.isNotEmpty);
  1. is关键字判断类型
var str ='ewewr';
if(str is String){
print('字符串类型');
}else{
print('其他类型');
}

运算符

取整运算符注意下写法:

print(a~/b);
v??=49;  

表示如果v为空的话把49赋值给v; 什么时候为为空?当定义了v但是没有赋值

  var sex="女";
  switch(sex){
    case "男":
      print('性别是男');
      break;
    case "女":
      print('性别是女');
      print('性别是女');
      break;
    default:
      print('传入参数错误');
      break;
  }

类型转换

Number类型转换成String类型toString()

var myNum=12;
var str=myNum.toString();
// 保留2位小数
var str1 = 3.14444.toStringAsFixed(2);
print(str is String);

String类型转换成Number类型int.parse()

String str='123';
var count = int.parse(str);
print(count is int);

转换要做异常处理

try {
}catch(err){
}

判断字符串是否为空

if(str.isEmpty){
print('字符串为空');
}

判断变量是否为空

var  temNum;
if (temNum == null){
print('空');
}

判断是否为同一个对象

使用identical()函数

判断值是否为NaN

if var ttt = 0/0;
if(ttt.isNaN){
print('NaN');
}

赋值运算中:++ -- 写在前面,表示先运算后赋值。如果写在后面表示先赋值,后运算

var a = 10;                                                    var a = 10;
var b = a++;                                                   var b = ++a;
(先把a赋值给了b,然后才自增) 
print(a);  //a = 11                                            print(a);  //a = 11 
print(b); //b = 10;                                           print(b); //b = 11;

continue 跳出当前本次循环 1层; break:跳出循环 多层

Dart中抽象类:

Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。
1、抽象类通过abstract 关键字来定义
2、Dart中的抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法。
3、如果子类继承抽象类必须得实现里面的抽象方法
4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
5、抽象类不能被实例化,只有继承它的子类可以

extends抽象类 和 implements的区别:
1、如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
2、如果只是把抽象类当做标准的话我们就用implements实现抽象类

抽象类里面的抽象方法,子类必须实现

Datr中的多态:
允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。
子类的实例赋值给父类的引用。
多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。

dart接口

首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
同样使用implements关键字进行实现。
但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
建议使用抽象类定义接口。

方法

自定义方法的基本格式:

返回类型  方法名称(参数1,参数2,...){
         方法体
        return 返回值;
}

String printUserInfo(){
  return 'this is str';
}

定义一个方法然后打印用户信息

 String printUserInfo(String username,int age){  //行参
        return "姓名:$username---年龄:$age";
    }
 print(printUserInfo('张三',20)); //实参

定义一个带可选参数的方法

String printUserInfo(String username,[int age]){  //行参
      if(age!=null){
        return "姓名:$username---年龄:$age";
      }
   return "姓名:$username---年龄保密";
}

print(printUserInfo('张三',21)); //实参
print(printUserInfo('张三'));

定义一个带默认参数的方法

    String printUserInfo(String username,[String sex='男',int age]){  //行参

      if(age!=null){
        return "姓名:$username---性别:$sex--年龄:$age";
      }
      return "姓名:$username---性别:$sex--年龄保密";
    }

  print(printUserInfo('张三'));
  print(printUserInfo('小李','女'));
  print(printUserInfo('小李','女',30));

定义一个命名参数的方法

String printUserInfo(String username,{int age,String sex='男'}){  //行参

      if(age!=null){
        return "姓名:$username---性别:$sex--年龄:$age";
      }
      return "姓名:$username---性别:$sex--年龄保密";
  }
  print(printUserInfo('张三',age:20,sex:'未知'));

箭头函数

  List list=['苹果','香蕉','西瓜'];
  list.forEach((value){
      print(value);
    });
  list.forEach((value)=>print(value));


  List list=[4,1,2,3,4];
  var newList=list.map((value){

        if(value>2){
          return value*2;
        }
        return value;
    });
    print(newList.toList());
    var newList=list.map((value)=>value>2?value*2:value);

闭包

  1. 全局变量特点: 全局变量常驻内存、污染全局
  2. 局部变量的特点: 不常驻内存会被垃圾机制回收
  • 闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)
  • 闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。
fn(){
        var a=123;  /*不会污染全局   常驻内存*/
        return(){           
          a++;          
          print(a);
        };        
     }     
var b=fn(); 
b();

Dart是一门使用类和单继承的面向对象语言,万物皆对象,所有的对象都是类的实例,并且所有的类都继承自Object类,一个类通常由属性和方法组成。

自定义类的默认构造函数

class Person{
  String name;
  int age; 
  //默认构造函数
  Person(String name,int age){
      this.name=name;
      this.age=age;
  }
  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

class Person{
  String name;
  int age; 
  //默认构造函数的简写
  Person(this.name,this.age);
  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

void main(){
  Person p1=new Person('张三',20);
  p1.printInfo();
  Person p2=new Person('李四',25);
  p2.printInfo();
}

命名函数

class Person{
  String name;
  int age; 
  //默认构造函数的简写
  Person(this.name,this.age);
  
  Person.now(){
    print('我是命名构造函数');
  }

  Person.setInfo(String name,int age){
    this.name=name;
    this.age=age;
  }

  void printInfo(){   
    print("${this.name}----${this.age}");
  }
}

void main(){
  //Person p1=new Person('张三', 20);   //默认实例化类的时候调用的是 默认构造函数
  //Person p1=new Person.now();   //命名构造函数
  Person p1=new Person.setInfo('李四',30);
  p1.printInfo(); 
}

Dart中我们也可以在构造函数体运行之前初始化实例变量

class Rect{
  int height;
  int width;
  Rect():height=2,width=10{
    print("${this.height}---${this.width}");
  }

  getArea(){
    return this.height*this.width;
  } 
}

void main(){
  Rect r=new Rect();
  print(r.getArea()); 
}

私有属性和方法

Dart和其他面向对象语言不一样,没有 public private protected这些访问修饰符。但是我们可以使用"_"下划线,把一个属性或者方法定义成私有。

class Animal{
  String _name;   //私有属性
  int age; 
  //默认构造函数的简写
  Animal(this._name,this.age);

  void printInfo(){   
    print("${this._name}----${this.age}");
  }

  String getName(){ 
    return this._name;
  } 
  void _run(){
    print('这是一个私有方法');
  }

  execRun(){
    this._run();  //类里面方法的相互调用
  }
}

import 'lib/Animal.dart';

void main(){
 Animal a=new Animal('小狗', 3);
 print(a.getName());
  a.execRun();   //间接的调用私有方法
}

类的getter和setter方法

class Rect{
  num height;
  num width;   
  Rect(this.height,this.width);
  get area{
    return this.height*this.width;
  }
}

void main(){
  Rect r=new Rect(10,2);
  print("面积:${r.area}");      //注意调用直接通过访问属性的方式访问area
}


class Rect{
  num height;
  num width; 
  Rect(this.height,this.width);
  get area{
    return this.height*this.width;
  }
  set areaHeight(value){
    this.height=value;
  }
}

void main(){
  Rect r=new Rect(10,4);
  // print("面积:${r.area()}");   
  r.areaHeight=6;
  print(r.area);
}

静态成员、方法

使用static 关键字来实现类级别的变量和函数;静态方法不能访问非静态成员,非静态方法可以访问静态成员

class Person {
  static String name = '张三';
  int age=20;
  
  static void show() {
    print(name);
  }

  void printInfo(){  /*非静态方法可以访问静态成员以及非静态成员*/
      // print(name);  //访问静态属性
      // print(this.age);  //访问非静态属性
      show();   //调用静态方法
  }

  static void printUserInfo(){//静态方法
        print(name);   //静态属性
        show();        //静态方法
        //print(this.age);     //静态方法没法访问非静态的属性
        // this.printInfo();   //静态方法没法访问非静态的方法
        // printInfo();
  }
}

对象操作符

? 条件运算符
as 类型转换
is 类型判断
.. 级联操作 (连缀)

class Person {
  String name;
  num age;
  Person(this.name,this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

   Person p1=new Person('张三1', 20);
   p1.printInfo();
   p1..name="李四"
     ..age=30
     ..printInfo();
级联操作

继承

Dart中的类的继承:
1. 子类使用extends关键词来继承父类
2. 子类会继承父类里面可见的属性和方法 但是不会继承构造函数
3. 子类能复写父类的方法 getter和setter

class Person {
  String name='张三';
  num age=20; 
  void printInfo() {
    print("${this.name}---${this.age}");  
  } 
}
class Web extends Person{

}

main(){   
  Web w=new Web();
  print(w.name);
  w.printInfo();
}

super关键词的使用

class Person {
  String name;
  num age; 
  Person(this.name,this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
}

class Web extends Person{
  Web(String name, num age) : super(name, age){

  }
}

main(){ 
  Web w=new Web('张三', 12);
  w.printInfo();
}

************************************
class Web extends Person{
  String sex;
  Web(String name, num age,String sex) : super(name, age){
    this.sex=sex;
  }
  run(){
   print("${this.name}---${this.age}--${this.sex}");  
  }
}

main(){ 
  Web w=new Web('张三', 12,"男");
  w.printInfo();
  w.run();
}

继承命名构造函数

class Person {
  String name;
  num age; 
  Person(this.name,this.age);
  Person.xxx(this.name,this.age);
}

class Web extends Person{
  String sex;
  Web(String name, num age,String sex) : super.xxx(name, age){
    this.sex=sex;
  }
  run(){
   print("${this.name}---${this.age}--${this.sex}");  
  }
  
}

main(){ 
  Web w=new Web('张三', 12,"男");
  w.run();
}

覆写父类方法

class Person {
  String name;
  num age; 
  Person(this.name,this.age);
  void printInfo() {
    print("${this.name}---${this.age}");  
  }
  work(){
    print("${this.name}在工作...");
  }
}

class Web extends Person{
  Web(String name, num age) : super(name, age);
  run(){
    print('run');
  }
  //覆写父类的方法
  @override       //可以写也可以不写  建议在覆写父类方法的时候加上 @override 
  void printInfo(){
     print("姓名:${this.name}---年龄:${this.age}"); 
  }
  @override
  work(){
    print("${this.name}的工作是写代码");
  }
}

main(){ 
  Web w=new Web('李四',20);
  w.printInfo();
  w.work();
}

子类调用父类方法

class Person {
  String name;
  num age; 
  Person(this.name,this.age);
  work(){
    print("${this.name}在工作...");
  }
}

class Web extends Person{
  Web(String name, num age) : super(name, age);
  run(){
    print('run');
    super.work();  //自类调用父类的方法
  }
}

main(){ 
  Web w=new Web('李四',20);
  w.run();
}

抽象类

主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口

  1. 抽象类通过abstract 关键字来定义
  2. 抽象方法不能用abstract声明,Dart中没有方法体的方法我们称为抽象方法
  3. 如果子类继承抽象类必须得实现里面的抽象方法
  4. 如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法
  5. 抽象类不能被实例化,只有继承它的子类可以

extends抽象类 和 implements的区别:

  1. 如果要复用抽象类里面的方法,并且要用抽象方法约束自类的话我们就用extends继承抽象类
  2. 如果只是把抽象类当做标准的话我们就用implements实现抽象类

定义一个Animal 类要求它的子类必须包含eat方法

abstract class Animal{
  eat();   //抽象方法
  run();  //抽象方法  
  printInfo(){
    print('我是一个抽象类里面的普通方法');
  }
}

class Dog extends Animal{
  @override
  eat() {
     print('小狗在吃骨头');
  }

  @override
  run() {
    // TODO: implement run
    print('小狗在跑');
  }  
}

class Cat extends Animal{
  @override
  eat() {
    // TODO: implement eat
    print('小猫在吃老鼠');
  }

  @override
  run() {
    // TODO: implement run
    print('小猫在跑');
  }
}

main(){
  Dog d=new Dog();
  d.eat();
  d.printInfo();
   Cat c=new Cat();
  c.eat();
  c.printInfo();
  // Animal a=new Animal();   //抽象类没法直接被实例化
}

多态:父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。

abstract class Animal{
  eat();   //抽象方法 
}

class Dog extends Animal{
  @override
  eat() {
     print('小狗在吃骨头');
  }
  run(){
    print('run');
  }
}

class Cat extends Animal{
  @override
  eat() {   
    print('小猫在吃老鼠');
  }
  run(){
    print('run');
  }
}

main(){
  Animal d=new Dog();
  d.eat();
  Animal c=new Cat();
  c.eat();
}

接口

和Java一样,dart也有接口,但是和Java还是有区别的。

  • 首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现。
  • 同样使用implements关键字进行实现。
  • 但是dart的接口有点奇怪,如果实现的类是普通类,会将普通类和抽象中的属性的方法全部需要覆写一遍。
  • 而因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现像Java接口那样的方式,一般会使用抽象类。
    建议使用抽象类定义接口
abstract class Db{   //当做接口   接口:就是约定 、规范
    String uri;      //数据库的链接地址
    add(String data);
    save();
    delete();
}

class Mysql implements Db{
  
  @override
  String uri;

  Mysql(this.uri);

  @override
  add(data) {
    // TODO: implement add
    print('这是mysql的add方法'+data);
  }

  @override
  delete() {
    // TODO: implement delete
    return null;
  }

  @override
  save() {
    // TODO: implement save
    return null;
  }

  remove(){
  }
}

class MsSql implements Db{
  @override
  String uri;
  @override
  add(String data) {
    print('这是mssql的add方法'+data);
  }

  @override
  delete() {
    // TODO: implement delete
    return null;
  }

  @override
  save() {
    // TODO: implement save
    return null;
  }
}

main() {
  Mysql mysql=new Mysql('xxxxxx');
  mysql.add('1243214');
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 一. Dart入口方法 每一个flutter项目的lib目录里面都有一个main.dart。这个文件就是flutt...
    骑马纵天下阅读 2,475评论 0 0
  • Dart我们有不得不学的理由,因为有Flutter这尊大神在啊,但是像有的大神这样潇洒,现阶段我还做不到 如果您熟...
    前行的乌龟阅读 2,260评论 0 12
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,603评论 0 11
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,065评论 1 32
  • 原文地址 1、创建主工程 path: /Users/Funky/Desktop/CocoaPodRemoteLib...
    Mr卿阅读 269评论 0 2