Flutter入门02----Dart语法

2022-01-06  本文已影响0人  zyc_在路上

VSCode环境搭建

main函数

声明变量

main(List<String> args) {
  //1.明确的声明
  String name = "zyc";

  //2.类型推导(var/final/const)
  //2.1 var声明变量
  var age = 20;

  //2.2 final声明常量
  final weight = 2.55;

  //2.3 const声明常量
  const address = "南京";

  //final与const的区别
  // const date1 = DateTime.now();
  final date2 = DateTime.now();

  final p1 = Person("zyc");
  final p2 = Person("zyc");

  print(identical(p1, p2)); //false

  const s1 = Student("123");
  const s2 = Student("123");

  print(identical(s1, s2)); //true

}

class Person {
  String name;

  Person(String name) {
    this.name = name;
  }
}

class Student {
  final String name;

  const Student(this.name);
}

数据类型

main(List<String> args) {
  //1.定义字符串
  var str1 = 'abc';
  var str2 = "abc";
  var str3 = """
  abc
  ass
  sss
  """;
  //2.字符串拼接
  var name = "zyc";
  var age = 31;
  var height = 188;

  var message1 = "my name is ${name},age is ${age},height is ${height}";
  var message2 = "name is ${name},type is ${name.runtimeType}";

  print(message1); //my name is zyc,age is 31,height is 188
  print(message2); //name is zyc,type is String
}
main(List<String> args) {
  //1.数组List
  var names = ["abc", "sss", "asd"];
  names.add("fff");
  names.remove("sss");
  names.removeAt(1);

  //2.集合Set
  var movies = {"大话西游", "2012", "大白鲨"};
  movies.add("长津湖");

  //3.映射map
  var info = {"name": "zyc", "age": 20, "height": 175};
  bool isNameKey = info.containsKey("name");
  print(isNameKey); 
  print(info.keys); //所有key
  print(info.values); //所有value
}

函数

函数的定义
main(List<String> args) {
  print(sum(10, 30));
}

//1.返回值类型可以省略,开发中不推荐这么写
int sum(int num1, int num2) {
  return num1 + num2;
}
函数的参数
main(List<String> args) {
  sayHello1("zyc");

  sayHello2("zyc", 18, 175.5);

  sayHello3("zyc", age: 31, height: 175);
  sayHello3("wangwu", height: 172);
  sayHello3("zhuliu", age: 33);
  sayHello3("nima", height: 144, age: 55);
}

//1.必选参数:必须传
void sayHello1(String name) {
  print(name);
}

//Dart中没有函数的重载
//2.可选参数:位置可选参数 / 命名可选参数
//可选参数可以支持有默认值
//2.1.位置可选参数:[int age,double height]
//实参和行参在进行匹配时,是根据位置匹配的
void sayHello2(String name, [int age = 22, double height = 123.4]) {
  print(name);
  print(age);
  print(height);
}

//2.2.命名可选参数 {int age,double height }
void sayHello3(String name, {int age = 32, double height = 56.9}) {
  print(name);
  print(age);
  print(height);
}
函数是一等公民
main(List<String> args) {
  //1.函数作为参数
  test1(shit);

  //2.匿名函数: (参数列表) {函数体}
  test2(() {
    print("匿名函数被调用");
    return 10;
  });

  //3.箭头函数:函数体只有一行代码
  test1(() => print("箭头函数被调用"));

  test3((num1, num2) {
    return num1 + num2;
  });

  test4((num1, num2) {
    return num1 + num2;
  });

  var demo1 = demo();
  print(demo1(30, 40));
}

//函数可以作为参数
void test1(Function foo) {
  foo();
}

void test2(Function foo) {
  var result = foo();
  print(result);
}
//4.明确函数类型
typedef Calculate = int Function(int num1, int num2);

void test3(int foo(int num1, int num2)) {
  var result = foo(20, 30);
  print(result);
}

void test4(Calculate cal) {
  print(cal(100, 200));
}

//5.函数作为返回值
Calculate demo() {
  return (num1, num2) {
    return num1 * num2;
  };
}

void shit() {
  print("shit函数被调用");
}

运算符

赋值运算符
main(List<String> args) {
  //??=
  //当原来的变量有值时,那么??=不执行
  //当原来的变量为null,那么将值赋值给这个变量
  var name1 = "zyc";
  name1 ??= "shit";
  print(name1); //zyc

  var age = null;
  age ??= 100;
  print(age); //100

  //??
  //??前面的数据有值,那么就使用??前面的数据
  //??前面的数据为null,那么就使用??后面的数据
  var name2 = "SF";
  var temp2 = name2 ?? "SFFF";
  print(temp2); //SF

  var name3 = null;
  var temp3 = name2 ?? "SFFF";
  print(temp3); //SFFF
}
级联运算符
main(List<String> args) {
  var p = Person();
  p.name = "SF";
  p.run();
  p.eat();

  //..级联运算符
  var p1 = Person()
    ..name = "SF"
    ..eat()
    ..run();
}

class Person {
  String name;

  void run() {
    print("run");
  }

  void eat() {
    print("eat");
  }
}

类与对象

构造函数
main(List<String> args) {
  var p = Person("SF", 27);

  var p1 = Person.withNameAgeHeight("zyc", 31, 175.0);

  var p2 = Person.fromMap({"name": "zyc", "age": 31, "height": 175.2});
  print(p2);

  //Object和dynamic的区别
  //Object在调用方法,编译时会报错;
  //dynamic在调用方法时,编译时不会报错,但是运行时会存在安全隐患
  // Object obj1 = "zyc";
  // print(obj1.substring(1));

  //明确的类型声明
  // dynamic obj2 = "zyc";
  // print(obj2.substring(1));
  
  //dynamic obj3 = 123;
  //print(obj3.substring(1)); //运行时会报错
}

class Person {
  String name;
  int age;
  double height;

  //构造函数
  // Person(String name, int age) {
  //   this.name = name;
  //   this.age = age;
  // }
 
  //语法糖
  Person(this.name, this.age);

  //命名构造函数
  Person.withNameAgeHeight(this.name, this.age, this.height);

  Person.fromMap(Map<String, dynamic> map) {
    this.name = map["name"];
    this.age = map["age"];
    this.height = map["height"];
  }

  @override
  String toString() {
    return "$name $age $height";
  }
}
初始化列表
main(List<String> args) {
  var p = Person("SF");
  print(p.age);
}

class Person {
  //被final修饰的变量为常量 只能被赋值一次
  final String name;
  final int age;

  //初始化列表与C++语法类似
  //创建对象时,若传入age,那么就使用传入的age,如果没有传入age,那么使用默认值,age为可选参数
  Person(this.name, {int age}) : this.age = age ?? 10 {
  //在执行此大括号的代码时,对象已经初始化完毕了
  //必须保证在执行此大括号的代码之前,final修饰的name与age必须已经初始化
  //所以下面代码报错
  //this.age = 10;
  }

  //存在局限性 
  //Person(this.name, {this.age = 10});
}
重定向构造函数
main(List<String> args) {
  var p = Person("SF");
  print(p.age); //22
}

class Person {
  String name;
  int age;

  //调用自定义构造函数Person._internal
  Person(String name) : this._internal(name, 22);

  Person._internal(this.name, this.age);
}
常量构造函数
main(List<String> args) {
  const p1 = Person("zyc");
  const p2 = Person("zyc");
  
  //p1与p2是同一个对象
  print(identical(p1, p2)); 
}

class Person {
  final String name;

  const Person(this.name);
}
工厂构造函数
main(List<String> args) {

  final p1 = Person.withName("zyc");
  final p2 = Person.withName("zyc");

  print(identical(p1, p2)); //true
}

class Person {
  //对象属性
  String name;
  String color;

  //类属性
  static final Map<String, Person> _nameCache = {};
  static final Map<String, Person> _colorCache = {};

  //工厂构造函数
  //1.根据key值从缓存中获取对象,存在直接返回,不存在
  factory Person.withName(String name) {
    if (_nameCache.containsKey(name)) {
      return _nameCache[name];
    } else {
      final p = Person(name, "default");
      _nameCache[name] = p;
      return p;
    }
  }

  factory Person.withColor(String color) {
    if (_colorCache.containsKey(color)) {
      return _colorCache[color];
    } else {
      final p = Person("default", color);
      _colorCache[color] = p;
      return p;
    }
  }

  Person(this.name, this.color);
}
setter与getter方法
main(List<String> args) {
  final p = Person();

  //直接访问属性
  p.name = "zyc";
  print(p.name);

  //通过setter与getter访问属性
  p.setName = "SF";
  print(p.getName);

  p.setAge = 31;
  print(p.age);
}

class Person {
  String name;
  int age;

  //setter
  set setName(String name) {
    this.name = name;
  }

  set setAge(int age) => this.age = age;

  //getter
  String get getName {
    return name;
  }

  int get getAge => age;
}
类的继承
main(List<String> args) {}

class Animal {
  int age;

  Animal(this.age);
}

class Person extends Animal {
  String name;
  
  //必须完成父类属性age的初始化 在初始化列表中完成
  Person(this.name, int age) : super(age);
}
抽象类
main(List<String> args) {
  //抽象类不能实例化
  //final s = Shape();

  //Map是系统的一个抽象类
  //Map能实例化 是因为Map内部实现了一个工厂构造函数 external factory Map()
  final map = Map();
  print(map.runtimeType);
}

abstract class Shape {
  void getArea();
}

//继承抽象类的子类 必须实现抽象类中定义的抽象方法
class Rectanle extends Shape {
  @override
  void getArea() {
    print("画矩形");
  }
}
external关键字详解

说道抽象类abstract,就不得不说一下external关键字,external关键字估计用到人很少,在看源码的时侯经常可以看到,如下:

class Object {
  const Object();
  external bool operator ==(other);
  external int get hashCode;
  external String toString();
  @pragma("vm:entry-point")
  external dynamic noSuchMethod(Invocation invocation);
  external Type get runtimeType;
}
1、external作用
2、external声明方法实现
@patch
class 类名 {
  ...
  @patch
  external声明的方法名
  ...
}

external声明的方法,通过@patch注解实现结构如上
比如Object里各种external声明方法的实现如下

@patch
class Object {
  ...
  @patch
  bool operator ==(Object other) native "Object_equals";

  static final _hashCodeRnd = new Random();

  static int _objectHashCode(obj) {
    var result = _getHash(obj);
    if (result == 0) {
      // We want the hash to be a Smi value greater than 0.
      result = _hashCodeRnd.nextInt(0x40000000);
      do {
        result = _hashCodeRnd.nextInt(0x40000000);
      } while (result == 0);
      _setHash(obj, result);
    }
    return result;
  }

  @patch
  int get hashCode => _objectHashCode(this);
  

  @patch
  String toString() native "Object_toString";

  @patch
  @pragma("vm:exact-result-type", "dart:core#_Type")
  Type get runtimeType native "Object_runtimeType";
  ...
}

隐式接口

main(List<String> args) {
  
}

class Animal {
  void eat() {
    print("eat");
  }
}

class Runnner {
  void run() {
    print("run");
  }
}

class Flyer {
  void fly() {
    print("fly");
  }
}

//当将一个类当作接口使用时,那么实现这个接口的类,必须实现这个接口中的所有方法
class Superman extends Animal implements Runnner, Flyer {

  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }

  @override
  void run() {
    // TODO: implement run
  }

  @override
  void fly() {
    // TODO: implement fly
  }
}
混入mixin
main(List<String> args) {
  final sm = Superman();
  sm.run();
  sm.fly();
  sm.eat();
}

class Animal {
  void eat() {
    print("Animal eat");
  }
}

mixin Runnner {
  void run() {
    print("Runnner run");
  }
}

mixin Flyer {
  void fly() {
    print("Flyer fly");
  }
}

//当将一个类当作接口使用时,那么实现这个接口的类,必须实现这个接口中的所有方法
class Superman extends Animal with Runnner, Flyer {
  @override
  void eat() {
    // TODO: implement eat
    super.eat();
  }

  @override
  void run() {
    // TODO: implement run
    super.run();
    print("Superman run");
  }
}
类成员和方法 => 静态static成员和方法
main(List<String> args) {
  final p = Person();
  p.name = "zyc";
  p.eat();

  Person.color = "yellow";
  print(Person.color);
  Person.run();
}

class Person {
  //成员属性 对象属性
  String name;

  //静态成员属性 类属性
  static String color;

  void eat() {
    print("Person eat");
  }

  static void run() {
    print("Person run");
  }
}
枚举
main(List<String> args) {
  final color = Colors.red;

  switch (color) {
    case Colors.red:
      print("红色");
      break;
    case Colors.green:
      print("灰色");
      break;
    case Colors.blue:
      print("蓝色");
      break;
    default:
  }
  //获取枚举的所有值
  print(Colors.values);
  //获取枚举值的index
  print(Colors.red.index);
}

enum Colors { red, green, blue }
泛型
扩展Extension
import 'package:Fluter01/day01/shared/SFSizeFit.dart';
import 'package:flutter/material.dart';

void main() => runApp(SFMyApp());

class SFMyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final String message = "Hello World";
    final result = message.sf_split(" ");

    print(result);
    return MaterialApp(home: SFHomePage());
  }
}

class SFHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("基础widget")),
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            color: Colors.red,
          ),
        )
    );
  }
}

extension StringSplit on String {
  List<String> sf_split(String split) {
    return this.split(split);
  }
}
库的使用
import 'dart:async';
import 'dart:math';

main(List<String> args) {
  final num1 = 10;
  final num2 = 30;
  //min函数 属于 dart:math系统库
  print(min(num1, num2));
}
3.png
import 'Utils/math_utils.dart' as SFUtils;

main(List<String> args) {
  //通过库的别名来调用函数方法
  print(SFUtils.sum1(10, 20));
}

int sum1(int num1, num2) {
  print("...");
  return num1 + num2;
}
import 'Utils/math_utils.dart' show sum1;

main(List<String> args) {
  //通过库的别名来调用函数方法
  print(SFUtils.sum1(10, 20));
}
import 'Utils/utils.dart';

main(List<String> args) {
  print(dateFormat());
  print(sum1(10, 20));
}
import 'package:http/http.dart' as http;

main(List<String> args) async {
  var url = Uri.https('www.googleapis.com', '/books/v1/volumes', {'q': '{http}'});
  var response = await http.get(url);
  if (response.statusCode == 200) {
    var jsonResponse = convert.jsonDecode(response.body) as Map<String, dynamic>;
    var itemCount = jsonResponse['totalItems'];
    print('Number of books about http: $itemCount.');
  } else {
    print('Request failed with status: ${response.statusCode}.');
  }
}
上一篇 下一篇

猜你喜欢

热点阅读