// Impport library: import 'dart:xxx' / 'package:xxx'// Specifying a library prefix: import 'package:lib2/lib2.dart' as lib2;// Importing only part of a library: import 'package:lib1/lib1.dart' show/hide foo;// Lazily loading a library: import 'package:greetings/hello.dart' deferred as hello;import'dart:math';voidmain(){testVariables();testBuiltInTypes();testFunctions();testOperators();testControlFlow();testExceptions();testClasses();testGenerics();testAsynchrony();test();}// VariablesvoidtestVariables(){print("Test Variables\n");// Constantsfinalname="Light";constage=26;print("name: $name age: $age");// Variablesvarweather="clear";weather="cloudy";print("weather: $weather");print("\n");}// Built-in typesvoidtestBuiltInTypes(){print("Test Built-in types\n");// Numbersvarinteger=2;varpi=3.1415926;varone=int.parse('1');assert(one==1);varonePointOne=double.parse('1.1');assert(onePointOne==1.1);vartwoAsString=integer.toString();assert(twoAsString=='2');varpiAsString=pi.toStringAsFixed(2);assert(piAsString=='3.14');assert((3<<1)==6);assert((3>>1)==1);assert((3|4)==7);// Stringsvars1='hello dart !';vars2="how are you";print('say hello: $s1');print('say grate: ${s2.toUpperCase()+' TOM ?'}');vars3=''' multy line string multy line string ''';print(s3);vars4='In a raw string, not even \n gets special treatment';print('not raw string: $s4');vars5=r'In a raw string, not even \n gets special treatment';print('raw string: $s5');// BooleansvarfullName='';assert(fullName.isEmpty);varhitPoints=0;assert(hitPoints<=0);varunicorn;assert(unicorn==null);variMeantToDoThis=0/0;assert(iMeantToDoThis.isNaN);// Listsvarlist=[1,2,3];print('list: $list');print('list length: ${list.length}');// MapsvarpersonInfo={'name':'Light','age':'26','sex':'male'};print('map: $personInfo');personInfo['birthday']='1992.12.09';print('map: $personInfo');print('map length: ${personInfo.length}');// Runesvarclapping='\u{1f44f}';print('clapping: $clapping');print('clapping code units: ${clapping.codeUnits}');print('clapping runes: ${clapping.runes.toList()}');Runesinput=newRunes('hello \u2665\u{1f605}\u{1f60e}\u{1f47b}\u{1f596}\u{1f44d}');print('runes: $input');print('string from runes: ${newString.fromCharCodes(input)}');// Symbolsprint(#radix);print(#bar);print("\n");}// FunctionsvoidtestFunctions(){print("Test Functions\n");// Optional parameters// Optional named parameters {}// Optional positional parameters []// Default parameter values = compile time const// The main() function// a top-level function, which serves as the entrypoint to the app// Function as first-class objects// pass a function as a parameter to another function// assign a function to a variable// Anonymous functions// ([Type] param1[, ...]) { codeBlock}// Lexical scope// "follow the curly braces outwards" to see if a variable is in scope// Lexical closures// A closure is a function object that has access to variables in its lexical scope// Return values// All function return a value. default return value is nullprint("\n");}// OperatorsvoidtestOperators(){print("Test Operators\n");print('5 / 2 = ${5/2}');print('5 ~/ 2 = ${5~/2}');print('5 % 2 = ${5%2}');// as is is!// ??=// ^ ~expr// expr1 ?? expr2// . ?. ..print("\n");}// Control flow statementsvoidtestControlFlow(){print("Test Control flow\n");// for loopsvarmessage=StringBuffer('Dart is fun');for(vari=0;i<5;i++){message.write('!');}print(message);// for infor(varxin[1,2,3]){print(x);}// forEach['a','b','c'].forEach((char)=>print(char));// switchvarcommand='CLOSED';switch(command){case'CLOSED':print('Closed');continueopen;open:case'OPEN':print('Open');break;default:print('Default');}print("\n");}// ExceptionsvoidtestExceptions(){print("Test Exceptions\n");// throw// rethrow// try on catch finallyprint("\n");}classPoint{// instantce variablesnumx,y;// static variablesstaticvarpointColor=Color.red;// convenient constructorsPoint(this.x,this.y);// named constructors with initializer listPoint.origin():x=0,y=0{print('create point (0, 0)');}// redirecting constructorsPoint.alongXAxis(numx):this(x,0);// instance methoddistanceTo(Pointp)=>sqrt((this.x-p.x)*(this.x-p.x)+(this.y-p.y)*(this.y-p.y));// gettergetdistanceToOrigin=>distanceTo(Point.origin());// static methodstaticnumdistanceBetween(Pointa,Pointb){vardx=a.x-b.x;vardy=a.y-b.y;returnsqrt(dx*dx+dy*dy);}}abstractclassDoer{// Define instance variables and methods...voiddoSomething();// Define an abstract method.}classEffectiveDoerextendsDoer{voiddoSomething(){// Provide an implementation, so the method is not abstract here...}}// A person. The implicit interface contains greet().classPerson{// In the interface, but visible only in this library.final\_name;// Not in the interface, since this is a constructor.Person(this.\_name);// In the interface.Stringgreet(Stringwho)=>'Hello, $who. I am $\_name.';}// An implementation of the Person interface.classImpostorimplementsPerson{get\_name=>'';Stringgreet(Stringwho)=>'Hi $who. Do you know who I am?';}StringgreetBob(Personperson)=>person.greet('Bob');enumColor{red,green,blue}// ClassesvoidtestClasses(){print("Test Classes\n");// Using constructorsvarp=Point.origin();// Using class members// Instance variablesprint('point: $p');print('distance between ${p.toString()} and (3, 4): ${p.distanceTo(Point(3,4))}');// Getting an objects's typeprint('The type of 1 is ${1.runtimeType}');// Constructors// Constructors aren’t inherited// Invoking a non-default superclass constructor// initializer list// superclass's no-arg constructor// main class's no-arg constructor// Specify the superclass constructor after a colon (:), just before the constructor body.// Initializer list// Redirecting constructors// Factory constructors, have no access to this// Methodsprint('Point (5, 6) distance to origin: ${Point(5,6).distanceToOrigin}');// Abstract classes// Abstract methods can only exist in abstract classes.// Abstract classes are useful for defining interfaces, often with some implementation.// Implicit interfacesprint(greetBob(Person('Kathy')));print(greetBob(Impostor()));// Extends a class// extends super methods// override super methods// override operators// noSuchMethod()// Enumerated typesprint(Color.values);print(Color.red);print(Color.red.index);// Adding features to a class: mixins// Mixins are a way of reusing a class’s code in multiple class hierarchies// Class variables and methodsprint('Point color: ${Point.pointColor}');print('distance between (2, 6) and (3, 4): ${Point.distanceBetween(Point(2,6),Point(3,4))}');print("\n");}// GenericsvoidtestGenerics(){print("Test Generics\n");// Using collection literalsvarnames=<String>['Seth','Kathy','Lars'];varpages=<String,String>{'index.html':'Homepage','robots.txt':'Hints for web robots','humans.txt':'We are people, not machines'};print(names);print(pages);print(names.runtimeType);// Restricting the parameterized type// Using generic methodsprint("\n");}// Asynchrony supportvoidtestAsynchrony(){print("Test Asynchrony\n");// Handling Futures// To use await, code must be in an async function—a function marked as async// Declaring async functions// An async function is a function whose body is marked with the async modifier// Handling Streams//print("\n");}//voidtest(){print("Test \n");print("\n");}
Swift 语言特性
- Swift 既是高级语言,又是低级语言。既可以使用 map 、 reduce 这样的方法,编写 高阶函数,又可以直接编译出原生的二进制可执行文件,具有和 C语言 媲美的性能。 (如何理解第二点?)
- Swift 是多范式语言。既可以 面向对象编程 ,又可以 函数式编程 。
- Swift 鼓励自下而上编程。可以自己构建组件。
- Swift 代码紧凑、精确,同时保持清晰。
- Swift 在实践中是相对安全的。(如何检查变量在被使用前是赋值的?)
- Swift 在不断的发展中。
使用 Material 自动布局 view.layout().top().left().width().height();
使用 SnapKit 自动布局 view.snp.makeConstrains{(make) in // layout};
使用 Extension 按功能模块分隔代码,相对清晰;
使用 Moya 封装网络模块请求;
使用 IGListKit 实现CollectionView,TableView;
使用 SwiftyUserDefaults 实现 UserDefault 存取;
使用 Realm 实现 数据库 存取;
使用 Codable 实现 JSON 解析;
2019.01.11
RxSwift
Every Observable sequence is just a sequence. The key advantage for an Observable vs Swift’s Sequence is that it can also receive elements asynchronously.
Observable(ObservableType) is equivalent to Sequence.
ObservableType.subscribe method is equivalent to Sequence.makeIterator method.
Observer (callback) needs to be passed to ObservableType.subscribe method to receive sequence elements instead of calling next() on the returned iterator.
When an observable is created, it doesn’t perform any work simply because it has been created.
However, if you just call a method that returns an Observable, no sequence generation is performed and there are no side effects. Observable just defines how the sequence is generated and what parameters are used for element generation. Sequence generation starts when subscribe method is called.