中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

做網(wǎng)站有2個前提條件 一個是網(wǎng)站如何做百度免費推廣

做網(wǎng)站有2個前提條件 一個是網(wǎng)站,如何做百度免費推廣,江山建設(shè)工程信息網(wǎng)站,電商app軟件開發(fā)說起宏編程可能大家并不陌生,但是這對于 Flutter 和 Dart 開發(fā)者來說它一直是一個「遺憾」,這個「遺憾」體現(xiàn)在編輯過程的代碼修改支持上,其中最典型的莫過于 Dart 的 JSON 序列化。 舉個例子,目前 Dart 語言的 JSON 序列化高度依…

說起宏編程可能大家并不陌生,但是這對于 Flutter 和 Dart 開發(fā)者來說它一直是一個「遺憾」,這個「遺憾」體現(xiàn)在編輯過程的代碼修改支持上,其中最典型的莫過于 Dart 的 JSON 序列化。

舉個例子,目前 Dart 語言的 JSON 序列化高度依賴 build_runner 去生成 Dart 代碼,例如在實際使用中我們需要:

  • 依賴 json_serializable ,通過注解聲明一個 Event 對象
  • 運行 flutter packages pub run build_runner build 生成文件
  • 得到 Event.g.dart 文件,在項目中使用它去實現(xiàn) JSON 的序列化和反序列化

這里最大的問題在于,我們需要通過命令行去生成一個項目文件,并且這個文件我們還可以隨意手動修改,從開發(fā)角度來說,這并不優(yōu)雅也不方便。

而宏聲明是用戶定義的 Dart 類,它可以實現(xiàn)一個或多個新的內(nèi)置宏接口,Dart 中的宏是用正常的命令式 Dart 代碼來開發(fā),不存在單獨的“宏語言”。

大多數(shù)宏并不是簡單地從頭開始生成新代碼,而是根據(jù)程序的現(xiàn)有屬性去添加代碼,例如向 Class 添加 JSON 序列化的宏,可能會查看 Class 聲明的字段,并從中合成一個 toJson() ,將這些字段序列化為 JSON 對象。

我們首先看一段官方的 Demo , 如下代碼所示,可以看到 :

  • MyState 添加了一個自定義的 @AutoDispose() 注解,這是一個開發(fā)者自己實現(xiàn)的宏聲明,并且繼承了 State 對象,帶有 dispose 方法。
  • MyState 里有多個 a a2 、bc 三個對象,其中 a 、a2 、b 都實現(xiàn)了 Disposable 接口,都有 dispose 方法
  • 雖然 a 、a2bMyStatedispose(); 方法來自不同基類實現(xiàn),但是基于 @AutoDispose() 的實現(xiàn),在代碼調(diào)用 state.dispose(); 時, a 、a2 、b 變量的 dispose 方法也會被同步調(diào)用
import 'package:macro_proposal/auto_dispose.dart';void main() {var state = MyState(a: ADisposable(), b: BDisposable(), c: 'hello world');state.dispose();
}()
class MyState extends State {final ADisposable a;final ADisposable? a2;final BDisposable b;final String c;MyState({required this.a, this.a2, required this.b, required this.c});String toString() => 'MyState!';
}class State {void dispose() {print('disposing of $this');}
}class ADisposable implements Disposable {void dispose() {print('disposing of ADisposable');}
}class BDisposable implements Disposable {void dispose() {print('disposing of BDisposable');}
}

如下圖所示,可以看到,盡管 MyState 沒用主動調(diào)用 a 、a2 、b 變量的 dispose 方法,并且它們和 MyStatedispose 也來自不同基類,但是最終執(zhí)行所有 dispose 方法都被成功調(diào)用,這就是@AutoDispose() 的宏聲明實現(xiàn)在編譯時對代碼進(jìn)行了調(diào)整。

如下圖所示是 @AutoDispose() 的宏編程實現(xiàn),其中 macro 就是一個標(biāo)志性的宏關(guān)鍵字,剩下的代碼可以看到基本就是 dart 腳本的實現(xiàn), macro 里主要是實現(xiàn) ClassDeclarationsMacrobuildDeclarationsForClass方法,如下代碼可以很直觀看到關(guān)于 super.dispose();disposeCalls 的相關(guān)實現(xiàn)。

import 'package:_fe_analyzer_shared/src/macros/api.dart';// Interface for disposable things.
abstract class Disposable {void dispose();
}macro class AutoDispose implements ClassDeclarationsMacro, ClassDefinitionMacro {const AutoDispose();void buildDeclarationsForClass(ClassDeclaration clazz, MemberDeclarationBuilder builder) async {var methods = await builder.methodsOf(clazz);if (methods.any((d) => d.identifier.name == 'dispose')) {// Don't need to add the dispose method, it already exists.return;}builder.declareInType(DeclarationCode.fromParts([// TODO: Remove external once the CFE supports it.'external void dispose();',]));}Future<void> buildDefinitionForClass(ClassDeclaration clazz, TypeDefinitionBuilder builder) async {var disposableIdentifier =// ignore: deprecated_member_useawait builder.resolveIdentifier(Uri.parse('package:macro_proposal/auto_dispose.dart'),'Disposable');var disposableType = await builder.resolve(NamedTypeAnnotationCode(name: disposableIdentifier));var disposeCalls = <Code>[];var fields = await builder.fieldsOf(clazz);for (var field in fields) {var type = await builder.resolve(field.type.code);if (!await type.isSubtypeOf(disposableType)) continue;disposeCalls.add(RawCode.fromParts(['\n',field.identifier,if (field.type.isNullable) '?','.dispose();',]));}// Augment the dispose method by injecting all the new dispose calls after// either a call to `augmented()` or `super.dispose()`, depending on if// there already is an existing body to call.//// If there was an existing body, it is responsible for calling// `super.dispose()`.var disposeMethod = (await builder.methodsOf(clazz)).firstWhere((method) => method.identifier.name == 'dispose');var disposeBuilder = await builder.buildMethod(disposeMethod.identifier);disposeBuilder.augment(FunctionBodyCode.fromParts(['{\n',if (disposeMethod.hasExternal || !disposeMethod.hasBody)'super.dispose();'else'augmented();',...disposeCalls,'}',]));}
}

到這里大家應(yīng)該可以直觀感受到宏編程的魅力,上述 Demo 來自 dart-language 的 macros/example/auto_dispose_main ,其中 bin/ 目錄下的代碼是運行的腳本示例,lib/ 目錄下的代碼是宏編程實現(xiàn)的示例:

https://github.com/dart-lang/language/tree/main/working/macros/example

當(dāng)然,因為現(xiàn)在是實驗性階段,API 和穩(wěn)定性還有待商榷,所以想運行這些 Demo 還需要一些額外的處理,比如版本強關(guān)聯(lián),例如上述的 auto_dispose_main 例子:

  • 需要 dart sdk 3.4.0-97.0.dev ,目前你可以通過 master 分支下載這個 dark-sdk https://storage.googleapis.com/dart-archive/channels/main/raw/latest/sdk/dartsdk-macos-arm64-release.zip

  • 將 sdk 配置到環(huán)境變量,或者進(jìn)入到 dart sdk 的 bin 目錄執(zhí)行 ./dart --version 檢查版本

  • 進(jìn)入上訴的 example 下執(zhí)行 dart pub get,過程可能會有點長

  • 最后,執(zhí)行 dart --enable-experiment=macros bin/auto_dispose_main.dart 記得這個 dart 是你指定版本的 dart 。

另外,還有一個第三方例子是來自 millsteed 的 macros ,這是一個簡單的 JSON 序列化實現(xiàn) Demo ,并且可以直接不用額外下載 dark-sdk,通過某個 flutter 內(nèi)置 dart-sdk 版本就可以滿足條件:3.19.0-12.0.pre

在本地 Flutter 目錄下,切換到 git checkout 3.19.0-12.0.pre ,然后執(zhí)行 flutter doctor 初始化 dark sdk 即可。

代碼的實現(xiàn)很簡單,首先看 bin 下的示例,通過 @Model() GetUsersResponseUser 聲明為 JSON 對象,然后在運行時,宏編程會自動添加 fromJsontoJson 方式。

import 'dart:convert';import 'package:macros/model.dart';()
class User {User({required this.username,required this.password,});final String username;final String password;
}()
class GetUsersResponse {GetUsersResponse({required this.users,required this.pageNumber,required this.pageSize,});final List<User> users;final int pageNumber;final int pageSize;
}void main() {const body = '''{"users": [{"username": "ramon","password": "12345678"}],"pageNumber": 1,"pageSize": 30}''';final json = jsonDecode(body) as Map<String, dynamic>;final response = GetUsersResponse.fromJson(json);final ramon = response.users.first;final millsteed = ramon.copyWith(username: 'millsteed', password: '87654321');final newResponse = response.copyWith(users: [...response.users, millsteed]);print(const JsonEncoder.withIndent('  ').convert(newResponse));
}

Model 的宏實現(xiàn)就相對復(fù)雜一些,但是實際上就是將類似 freezed/ json_serializable 是實現(xiàn)調(diào)整到宏實現(xiàn)了,而最終效果就是,開發(fā)者使用起來更加優(yōu)雅了。

// ignore_for_file: depend_on_referenced_packages, implementation_importsimport 'dart:async';import 'package:_fe_analyzer_shared/src/macros/api.dart';macro class Model implements ClassDeclarationsMacro {const Model();static const _baseTypes = ['bool', 'double', 'int', 'num', 'String'];static const _collectionTypes = ['List'];Future<void> buildDeclarationsForClass(ClassDeclaration classDeclaration,MemberDeclarationBuilder builder,) async {final className = classDeclaration.identifier.name;final fields = await builder.fieldsOf(classDeclaration);final fieldNames = <String>[];final fieldTypes = <String, String>{};final fieldGenerics = <String, List<String>>{};for (final field in fields) {final fieldName = field.identifier.name;fieldNames.add(fieldName);final fieldType = (field.type.code as NamedTypeAnnotationCode).name.name;fieldTypes[fieldName] = fieldType;if (_collectionTypes.contains(fieldType)) {final generics = (field.type.code as NamedTypeAnnotationCode).typeArguments.map((e) => (e as NamedTypeAnnotationCode).name.name).toList();fieldGenerics[fieldName] = generics;}}final fieldTypesWithGenerics = fieldTypes.map((name, type) {final generics = fieldGenerics[name];return MapEntry(name,generics == null ? type : '$type<${generics.join(', ')}>',);},);_buildFromJson(builder, className, fieldNames, fieldTypes, fieldGenerics);_buildToJson(builder, fieldNames, fieldTypes);_buildCopyWith(builder, className, fieldNames, fieldTypesWithGenerics);_buildToString(builder, className, fieldNames);_buildEquals(builder, className, fieldNames);_buildHashCode(builder, fieldNames);}void _buildFromJson(MemberDeclarationBuilder builder,String className,List<String> fieldNames,Map<String, String> fieldTypes,Map<String, List<String>> fieldGenerics,) {final code = ['factory $className.fromJson(Map<String, dynamic> json) {'.indent(2),'return $className('.indent(4),for (final fieldName in fieldNames) ...[if (_baseTypes.contains(fieldTypes[fieldName])) ...["$fieldName: json['$fieldName'] as ${fieldTypes[fieldName]},".indent(6),] else if (_collectionTypes.contains(fieldTypes[fieldName])) ...["$fieldName: (json['$fieldName'] as List<dynamic>)".indent(6),'.whereType<Map<String, dynamic>>()'.indent(10),'.map(${fieldGenerics[fieldName]?.first}.fromJson)'.indent(10),'.toList(),'.indent(10),] else ...['$fieldName: ${fieldTypes[fieldName]}'".fromJson(json['$fieldName'] "'as Map<String, dynamic>),'.indent(6),],],');'.indent(4),'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}void _buildToJson(MemberDeclarationBuilder builder,List<String> fieldNames,Map<String, String> fieldTypes,) {final code = ['Map<String, dynamic> toJson() {'.indent(2),'return {'.indent(4),for (final fieldName in fieldNames) ...[if (_baseTypes.contains(fieldTypes[fieldName])) ...["'$fieldName': $fieldName,".indent(6),] else if (_collectionTypes.contains(fieldTypes[fieldName])) ...["'$fieldName': $fieldName.map((e) => e.toJson()).toList(),".indent(6),] else ...["'$fieldName': $fieldName.toJson(),".indent(6),],],'};'.indent(4),'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}void _buildCopyWith(MemberDeclarationBuilder builder,String className,List<String> fieldNames,Map<String, String> fieldTypes,) {final code = ['$className copyWith({'.indent(2),for (final fieldName in fieldNames) ...['${fieldTypes[fieldName]}? $fieldName,'.indent(4),],'}) {'.indent(2),'return $className('.indent(4),for (final fieldName in fieldNames) ...['$fieldName: $fieldName ?? this.$fieldName,'.indent(6),],');'.indent(4),'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}void _buildToString(MemberDeclarationBuilder builder,String className,List<String> fieldNames,) {final code = ['@override'.indent(2),'String toString() {'.indent(2),"return '$className('".indent(4),for (final fieldName in fieldNames) ...[if (fieldName != fieldNames.last) ...["'$fieldName: \$$fieldName, '".indent(8),] else ...["'$fieldName: \$$fieldName'".indent(8),],],"')';".indent(8),'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}void _buildEquals(MemberDeclarationBuilder builder,String className,List<String> fieldNames,) {final code = ['@override'.indent(2),'bool operator ==(Object other) {'.indent(2),'return other is $className &&'.indent(4),'runtimeType == other.runtimeType &&'.indent(8),for (final fieldName in fieldNames) ...[if (fieldName != fieldNames.last) ...['$fieldName == other.$fieldName &&'.indent(8),] else ...['$fieldName == other.$fieldName;'.indent(8),],],'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}void _buildHashCode(MemberDeclarationBuilder builder,List<String> fieldNames,) {final code = ['@override'.indent(2),'int get hashCode {'.indent(2),'return Object.hash('.indent(4),'runtimeType,'.indent(6),for (final fieldName in fieldNames) ...['$fieldName,'.indent(6),],');'.indent(4),'}'.indent(2),].join('\n');builder.declareInType(DeclarationCode.fromString(code));}
}extension on String {String indent(int length) {final space = StringBuffer();for (var i = 0; i < length; i++) {space.write(' ');}return '$space$this';}
}

目前宏還處于試驗性質(zhì)的階段,所以 API 還在調(diào)整,這也是為什么上面的例子需要指定 dart 版本的原因,另外宏目前規(guī)劃里還有一些要求,例如

  • 所有宏構(gòu)造函數(shù)都必須標(biāo)記為 const
  • 所有宏必須至少實現(xiàn)其中一個 Macro 接口
  • 宏不能是抽象對象
  • 宏 class 不能由其他宏生成
  • 宏 class 不能包含泛型類型參數(shù)
  • 每個宏接口都需要聲明宏類必須實現(xiàn)的方法,例如,在聲明階段應(yīng)用的 ClassDeclarationsMacro 及其buildDeclarationsForClass 方法。

未來規(guī)劃里,宏 API 可能會作為 Pub 包提供,通過庫 dart:_macros 來提供支持 ,具體還要等正式發(fā)布時 dart 團(tuán)隊的決策。

總的來說,這對于 dart 和 flutter 是一個重大的厲害消息,雖然宏編程并不是什么新鮮概念,該是 dart 終于可以優(yōu)雅地實現(xiàn) JSON 序列化,并且還是用 dart 來實現(xiàn),這對于 flutter 開發(fā)者來說,無疑是最好的新年禮物。

所以,新年快樂~我們節(jié)后再見~

http://www.risenshineclean.com/news/56990.html

相關(guān)文章:

  • 開發(fā)安卓app關(guān)鍵詞優(yōu)化的發(fā)展趨勢
  • wordpress移動友好度大揭秘搜索引擎優(yōu)化seo的英文全稱是
  • 網(wǎng)站建設(shè)是不是無形資產(chǎn)深圳債務(wù)優(yōu)化公司
  • 新聞發(fā)布網(wǎng)站如果做初學(xué)seo網(wǎng)站推廣需要怎么做
  • wordpress手機網(wǎng)站怎么做3天網(wǎng)站seo優(yōu)化成為超級品牌
  • 商丘做網(wǎng)站seoseo百度發(fā)包工具
  • 做網(wǎng)站最好的公司福州seo排名優(yōu)化
  • 望城區(qū)政府門戶網(wǎng)站建設(shè)局電商平臺推廣公司
  • 專業(yè)做網(wǎng)站公司 前景sem是什么意思
  • 網(wǎng)站優(yōu)化搜索查詢網(wǎng)站收錄
  • 企業(yè)網(wǎng)站建設(shè)方案新聞百度導(dǎo)航和百度地圖
  • 網(wǎng)站建設(shè)行業(yè)淘寶裝修模板排行榜軟件
  • 有什么網(wǎng)站可以做家教軟文廣告投放平臺
  • 上海裝修做網(wǎng)站的倒閉了百度seo排名優(yōu)化公司哪家強
  • 蘭州網(wǎng)站哪里做怎么做推廣和宣傳平臺
  • 戀愛網(wǎng)站建設(shè)谷歌推廣怎么樣
  • 免費合同模板網(wǎng)站海底撈口碑營銷
  • 成都網(wǎng)站建設(shè)服務(wù)全搜網(wǎng)
  • 懷化市委網(wǎng)站網(wǎng)站快速排名互點軟件
  • 杭州盤石做網(wǎng)站專業(yè)嗎做百度網(wǎng)站一年多少錢
  • 如果在網(wǎng)站暗藏鏈接商城做推廣廣安seo外包
  • 娛樂網(wǎng)站模板手機網(wǎng)頁設(shè)計制作網(wǎng)站
  • 阿里網(wǎng)站建設(shè)優(yōu)秀營銷軟文100篇
  • 微友說是做網(wǎng)站維護(hù)讓幫忙投注網(wǎng)店代運營騙局
  • 做網(wǎng)站博客怎么推廣雅思培訓(xùn)班價格一覽表
  • 做智能家居網(wǎng)站需要的參考文獻(xiàn)關(guān)鍵詞優(yōu)化公司推薦
  • 網(wǎng)站建設(shè)報價方案下載企業(yè)網(wǎng)站模板建站
  • 專業(yè)的app網(wǎng)站開發(fā)百度關(guān)鍵詞優(yōu)化多久上首頁
  • 可直接打開網(wǎng)站的網(wǎng)頁地推任務(wù)網(wǎng)
  • 網(wǎng)站安全如何做百度seo在線優(yōu)化