GVKun编程网logo

swift 学习资源 - Swift 语言指南(swift语言入门)

6

如果您想了解swift学习资源-Swift语言指南的相关知识,那么本文是一篇不可错过的文章,我们将对swift语言入门进行全面详尽的解释,并且为您提供关于Ajax学习资源中外都有、Android|iO

如果您想了解swift 学习资源 - Swift 语言指南的相关知识,那么本文是一篇不可错过的文章,我们将对swift语言入门进行全面详尽的解释,并且为您提供关于Ajax 学习资源 中外都有、Android|iOS - 学习资源 - 电子书资源、angular 学习资源、Dart 语言指南(二)的有价值的信息。

本文目录一览:

swift 学习资源 - Swift 语言指南(swift语言入门)

swift 学习资源 - Swift 语言指南(swift语言入门)

github :https://github.com/ipader/SwiftGuide





@SwiftLanguage更新于 2016-6-6,更新内容详见Issue 55。往期更新回顾详见《收录周报》

  这份指南汇集了 Swift 语言主流学习资源,并以开发者的视角整理编排。对于精选项目及文章,可直接访问《Swift 项目精选》和《Swift 文章精选》。还有开发者们自己维护的《Swift 开发者、项目、最佳实践》。当然也不能错过那些活跃、优秀的《开发者个人资料页》。

目录

  • 入门指引
  • 教程文章
  • 开源项目
  • 推荐网站
  • 开发工具
  • 媒体报道
  • 开放平台
  • Apple Watch 指南

入门指引

苹果为Swift(中文介绍)开发者提供的官方文档入口,包括概述,博客(中译镜像)及开发资源。其中以下几份文档(Swift 2.1)为入门级必备(iBooks 版):

  • Swift Programming Language(中文版|PDF 版BySwiftGG翻译组)

  • Start Developing iOS Apps

  • Using Swift with Cocoa and Objective-C(中文版By@CocoaChina)

苹果同时也维护着相应 Beta 版(Swift 2.2)文档:Swift Programming Language,Start Developing iOS Apps,Using Swift with Cocoa and Objective-C。

学习实践的角度,标准库示例代码Swift Standard Library.playground是很棒的学习伴侣。

教程方面,苹果力荐了斯坦福课程Stanford University: Developing iOS 8 Apps with Swift(中文字幕版By@网易公开课)

除以上所涉及入门级文档,iOS Developer Library还为开发者提供了更庞大、系统化的开发文档支持。

以下列举了几份已有第三方中文翻译文档:

  • App Extension Programming Guide(中译镜像)
  • iOS Human Interface Guidelines(中文版|PDF 版By@腾讯ISUX)
  • HomeKit Developer Guide(中文版By@CocoaChina)

值得称道的还有:苹果为Apple TV Tech Talks和WWDC 2015的视频添加简体中文字幕,从而方便中国开发者观看来自官方的权威技术分享。

对于 Swift 开源及跨平台开发的同学,可以关注swift.org

教程文章

开源项目

推荐网站

  • 苹果官方
    • Swift:Swift 概述、博客以及开发资源。
    • swift.org:开源后独立出来的 Swift 开源社区。
    • GitHub:apple:苹果在 GitHub 上的开源项目。
    • GitHub:apple/swift:swift 语言在 GitHub 上的开源项目。
  • ksm/SwiftInFlux:作者(Karol Mazur)将 Apple Developer Forums 上有关 Swift 特性、缺陷及变更讨论分类汇总并更新到 GitHub,具有很好的可读性。从中可以一窥 Swift 缺陷及未来潜在地变化。最关键地是有 Chris Lattner 及核心团队答疑解惑。
  • raywenderlich.com(中文版):由Ray Wenderlich创建,专注于开发高质量编程指南(近期优质Swift文章及视频教程不断),著名的iOS/OS X博客及开发教程网站,非常适合新手学习。近期第一时间出了三本 Swift 新书。
  • Natasha The Robot: 时髦码农不容错过的 Swift 开发实战教程类网站。为了简化学习复杂性,每一篇文章涵盖技术点单一又独立,配以开发步骤、运行结果以及代码等标准方式教授。难能可贵的是,它往往出品“追剧式”(最新开发特性或API跟进式)教程,实在是开发者必藏精品网站。
  • NShipster(中译版:@刘镇夫,April Peng,@李乐佳,@程序员付恒等翻译):著名开源作者Matt Thompson创建的开发技术博客网站,他开发了AFNetworking网络库,也是非常多产的开源作者。更多了解参考:《COCOA 潮人 MATTT THOMPSON》By@程序员付恒
  • jamesonquave.com:移动开发者,优秀个人博客(近期文章同样关注于Swift 语言,写得很优质)。同时他将于8/30发布一本新书《Developing iOS 8 Apps in Swift》(Learn To Make Real World iOS 8 Apps)及视频教程。
  • objc.io(中译版 By @onevcat 及其朋友们):"关于 Objective-C 最佳实践和先进技术的期刊。 由 Chris Eidhof,Daniel Eggert 和 Florian Kugler 成立于柏林。我们成立 objc.io 的目的是针对深入的、跟所有 iOS 和 OS X 开发者相关的技术话题创造一个正式的平台。“
  • iOSCreator:这类开发指引式教程对于初学者来讲,是直接明了的有效学习资源。推荐者@荧星诉语
  • iOS Dev Weekly:收录一周以来 iOS 开发资讯链接,并于周五发布。由Dave Verwer创办,他是一位 iPhone 和 iPad 开发者以及培训师。
  • Appcoda.com:质量很高的一个 iOS 开发教程站,其中iOS Programming Course这个专题很适合刚接触 iOS 开发的新手学习。
  • 中文 iOS/Mac 开发博客列表:By@唐巧_body
  • devtalking.com:高产的中译博客。翻译了官方博客 Swift Blog - Apple Developer,《App Extension Programming Guide》。参与翻译了《Swift Programming Language》等。
  • SwiftGG:一个走心的 Swift 翻译组,由《The Swift Programming Language》中文版翻译团队原班人马组成, 翻译的文章来源于国外的优秀 Swift 网站和博客,且全部获得作者和网站授权。
  • Swift Weekly Brief:“这个博客现在每周会将Swift开源中的重要讨论和提交整理成Open source Swift weekly brief,这对一线开发者尽早了解这门语言的动态情报很有帮助。By@崔康总编”。来源:Jesse Squires
  • iosdevtips.co:iOS Development Tips

  • 资源合集

    以下是其它开发者社区或 Swift 爱好者整理的有关 Swift 语言学习的资源列表。

    • SwiftEducation:“这是建立在 GitHub 上的一个 Swift 学习资料汇集,包括了有关幻灯和多个练手的应用程序源码。By @极客头条”。的确有不少基础实用的好教程。这对于基础学起的同学有福了。
    • Awesome-Swift-Education:整理地如此美妙的学习资源,实在让人太欢喜了。
    • matteocrippa/awesome-swift:这个版本的 Swift 资源集合内容丰富,分类也不错。作者:Matteo Crippa
    • 适合iOS开发者的 15 大网站推荐:的确很全、很主流的国外 iOS 开发者网站。
    • 码农周刊 -《Swift 特刊》
    • CocoaChina -《Swift 新手入门汇集帖》
    • CSDN_CODE -《Swift 编程语言资料大合集》
    • InfoQ -《学习苹果 Swift 语言的一些在线资源(英文)》
    • 刘兰涛 -《Swift 学习资源》By@懒桃儿吃桃儿
    • learnswift.tips:国外主流 Swift 学习资源集合。
    • Awesome iOS:一个 iOS 的各类优秀的开源项目集合。真不错!可惜Swift开源项目资源不足。
    • iOS Developer Tips:还是有关 iOS 的开发资源及文章合集。
    • Wolg/awesome-swift:一位俄罗斯朋友分类整理的 Swift 资源列表(有持续更新)。
    • Aufree/trip-to-iOS:显然作者很用心的做了非常深入的整理。它对于开发者拓展学习范围及开发知识面非常有益。
    • Robin Eggenkamp - Awesome Swift:“一个收集了很多 Swift 开发资源的网站”。
    • iOS 开发技术前线:“一个定期翻译、发布国内外iOS优质的技术、开源库、软件架构设计、测试等文章的开源项目”。主要翻译来源 Ray Wenderlich,App Coda,Medium。来源:@开发技术前线
    • 11个超棒的 iOS 开发学习网站:还算比较主流的归纳。不过,缺了raywenderlich.com 和 ioscreator.com 这两个重量级教程网站实在是不应该啊。

开发工具

1. 编程工具

  • Xcode 6 beta下载:苹果应用集成开发环境。支持 C/C++,Objective C,Swift 等。不用购买开发者计划,直接下载。
  • Textmate:Mac OS X 上一个可高度自定义的编辑器,尤其在我想做出一个快速改变但又不想等待 Xcode 加载的时候。该工具目前已经开源
  • Mou:OS X 上一款 Markdown 的编辑器。非常适用于编写自述文件、变更日志以及其他方面的内容。作者:罗晨
  • Sublime Text ($):Mac OS X 上另一款非常受欢迎的轻量级,可高度自定义的编辑器。
  • RunSwift:正在犹豫是否入手苹果电脑开始一段 Swift 编程旅程的同学们,或仅仅为了试验一段简单 Swift 代码又懒得打开 Xcode,可以试试这款 Web 版 Swift 编译环境 RunSwift。
  • InfinitApps - Bezel:“嫌 Xcode 6 目前提供的 Watch 模拟器不够直观?Bezel 是一个用于视觉预览 WatchKit 所开发程序效果的小工具,前提是你安装了 xScope 软件(Mac端)或 xScopeMirror(iPhone端)。 By@WatchKit开发”
  • Markdown -> Playground:该开源项目可将内含有 Swift 代码的 Markdown 自动转换为 Xcode Playgrounds 文件。喜欢用 Markdown 编辑的同学很激动吧。P.S. 这款工具写于 NodeJS,原因作者有交待。
  • iOS/Mac Autolayout Constraints:这个工具不错,很直观,布局时可以省不少工夫。推荐者:@荧星诉语
  • 在线生成 AppStore 审核用截图:便捷的生产力工具。免费,易操作,可自定义。

2. 代码管理

  • GitHub:声望日盛的资源分享之地。
  • GitHub for Mac:一个设计的非常美观的 git 客户端,不能取代你从命令行获得的所有功能,但使用起来非常简单。
  • GitCafe:GitCafe is a source code hosting service based on version control system Git。国内的代码托管服务,基于 Git,值得一提的是最近也推出了和 GitHub Pages 类似的服务 Gitcafe Pages。因为是在国内,所以相比较 GitHub 有速度优势,在网络环境差的情况下也许可以作为 GitHub 的备用。
  • Bitbucket:国外的代码托管服务,不同于 GitHub 的是,Bitbucket 可以免费建立 private 项目。
  • Git:分布式版本控制系统和源码管理系统,其优点是:快和简单易用。对于新手来说,可在此查看免费电子书籍。

3. Xcode 插件

  • CocoaPods:第三方库的管理利器,允许你简单地把第三方库整合进自己的应用中。对我个人来说,我基本上每个项目都使用 CocoaPods。
  • CocoaPods Xcode Plugin:一款 Xcode 插件,允许你直接从 Xcode 管理 CocoaPod 依赖。
  • onevcat/VVDocumenter-Xcode:快捷注释 Xcode 插件。By@onevcat
  • ColorSense:一款显示颜色数值的插件,还可以直接通过系统的ColorPicker来自动生成对应颜色代码
  • Xcode 优秀插件整理:持续保持整理更新的 Xcode 插件整理 By@ddapps
  • CodeEagle/SwiftCodeSnippets:自动下载指定 Xcode Snippet 源的 Xcode Plugin。项目缺省提供 Snippet 代码源burczyk/XcodeSwiftSnippets。
  • realm/SwiftLint:Realm 采用 Swift 编写的基于 GitHub's Swift Style Guide 规则的检查工具。除了命令行运行方式,也提供集成 Xcode 的方法。对于新团队,这样的工具可以自动约束大家遵循编程规范。
  • XCode 升级后插件失效的原理与修复办法:由一条命令引发的分析文章。@_TongJZ
  • feinstruktur/CoPilot:通过此插件,Xcode 可以协同编程了(采用 WebSocket 通讯)。如此强大的“黑工具”,不爱它能行吗。演示视频

4. 管理工具

  • swiftenv:Swift 版本管理器。类似 rvm(Ruby),nvm(Node.js)。
  • HomeBrew:OS X 上非常出色的包管理工具。
  • Transmit ($):一个Mac OS X 上 FTP 客户端,有着非常漂亮的用户界面和有用的功能。

5. 调试工具

  • mattt/fuckingclangwarnings.com:警告与语义对照表。以后再也不用为 Xcode 各种警告纠结啦!By@foogry

6. 设计工具

  • sketch:更适合开发应用的矢量设计工具。通过插件还支持与代码协同工作。推荐书籍:Learn Sketch 3

媒体报道

开放平台

Apple Watch 指南

Ajax 学习资源 中外都有

Ajax 学习资源 中外都有

AJAX开发人员的编译模式:http://www.ajaxpatterns.org/
•  XMLHttpRequest教程:“动态网页接口”:http://www.xml.com/pub/a/2005/02/09/xml-http-request.html
• JavaScript性能基准:http://blogs.ebusiness-apps.com/dave/?p=14
• AJAX资源:http://www.ajaxmatters.com/
• JavaScript规范:http://www.ecma-international.or/ ... ndards/Ecma-262.htm
• 介绍JavaScript对象标识:http://www.crockford.com/JSON/index.html
•  Mozilla 的Venkman JavaScript调试器:http://www.mozilla.org/projects/venkman/
•  XML DOM参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/
xmlsdk/html/e9da2722-7879-4e48-869c-7f16714e2824.asp
• Microsoft Dynamic HTML reference: http://msdn.microsoft.com/library/default.asp?url=/
workshop/author/dhtml/reference/dhtml_reference_entry.asp
• Gecko DOM Reference: http://www.mozilla.org/docs/dom/domref/
• "“移植IE应用到Mozilla”
http://www-128.ibm.com/developerworks/web/library/wa-ie2mozgd/
• Mozilla XUL reference:
http://www.xulplanet.com/
• Microsoft XAML reference:
http://windowssdk.msdn.microsoft/ ... t.asp?url=/library/
en-us/wcp_conceptual/html/0ff5f36e-dd84-44d1-aa3e-5bb4f147b169.asp?frame=true
• James Jesses Garret introduced the term AJAX in his article "AJAX: A New Approach to Web Applications," (Adaptive Path, February 2005): “AJAX:新的网页应用开发方式”
http://www.adaptivepath.com/publ ... archives/000385.php
• JetBrains IntelliJ IDEA:
http://www.jetbrains.com/
• Microsoft Visual Studio:
http://msdn.microsoft.com/vstudio/
• JSEditor:
http://jseditor.sourceforge.net/
• JSEclipse:
http://www.interaktonline.com/Pr ... JSEclipse/Overview/
• ActiveState Komodo:
http://www.activestate.com/Products/Komodo/
• XHTML:
http://www.w3.org/TR/xhtml1/
• Document Object Model:
http://www.w3.org/DOM/
• Cascading Style Sheets:
http://www.w3.org/Style/CSS/
• Extensible Stylesheet Language:
http://www.w3.org/Style/XSL/
• XForms:
http://www.w3.org/MarkUp/Forms/
• Scaling Vector Graphics:
http://www.w3.org/Graphics/SVG/
• XPath:
http://www.w3.org/TR/xpath
• AJAX.Net:
http://ajax.schwarz-interactive.de/csharpsample/default.aspx
• Backbase:
http://www.backbase.com/
• Bitkraft:
http://www.tiggrbitz.com/
• Django:
http://www.djangoproject.com/
• Dojo:
http://www.dojotoolkit.org/
• DWR (Direct Web Reporting):
http://getahead.ltd.uk/dwr/
• MochiKit:
http://mochikit.com/
• Prototype:
http://prototype.conio.net/
• Rico:
http://openrico.org/rico/home.page
• Sajax:
http://www.modernmethod.com/sajax/
• Sarissa:
http://sarissa.sourceforge.net/doc/
• Script.aculo.us:
http://script.aculo.us/
• Ruby on Rails:
http://www.rubyonrails.org/
• For more on AJAX and DWR, read "AJAX Made Simple with DWR," Cloves Carneiro Jr. (JavaWorld, June 2005): 关于AJAX和DWR,请阅读“AJAX使用DWR更简单”
http://www.javaworld.com/javaworld/jw-06-2005/jw-0620-dwr.html
• For more articles on Java development tools, browse the Development Tools section of JavaWorld''s Topical Index: 更多Java开发工具的文章,请浏览JavaWorld的开发工具部分索引页
http://www.javaworld.com/channel_content/jw-tools-index.shtml
• For more articles on XML, browse the Java and XML section of JavaWorld''s Topical Index: 更多XML的文章,请浏览JavaWorld的Java和XML部分索引页
http://www.javaworld.com/channel_content/jw-xml-index.shtml
• For more articles on UI design, browse the User Interface Design section of JavaWorld''s Topical Index: 更多UI设计的文章,请浏览JavaWorld的UI设计部分索引页
http://www.javaworld.com/channel_content/jw-ui-index.shtml

Android|iOS - 学习资源 - 电子书资源

Android|iOS - 学习资源 - 电子书资源

电子书资源常用网站:

 

站名 支持格式 科学S网 备注
txt pdf epub moib
鸠摩搜索    
布克书屋            
田间小站           英语报刊杂志
Z-Library           英语好书
爱分享读书            
SoBooks            
书享家            综合搜索

 

angular 学习资源

angular 学习资源

看百度百科的简介

  • 说明angular产生的原因

    在使用现有的技术创建web应用遇到问题,具体什么问题没有说。html 语言适合创建静态的应用,创建动态的文本应用,有不足;web应用就是创建一个有大量客户端交互的应用。对于静态的语言是个挑战。

    • angular是怎么解决的呢?

    主要是通过指令的概念,封装对DOM的操作

    • 类库和框架的区别在哪?

    简介中也有提到,使用框架开发应用,在应用中主导者是框架不是我们的逻辑代码,而使用类库,主导者是我们逻辑代码,什么时候使用这些类库是由我们写代码决定的,和框架是相反的。框架是创建了一个我们逻辑代码运行的环境,具体什么时候运行我们的代码,是由整个环境决定的。

简单概念的理解

  • 大量对angular 概念的介绍
  • 简单的实例

学习遇到的问题

基本知识掌握之后,通过一个比较完整的实例练习,但是很多的实例需要各种的工具的配置。在学习angular之前需要了解很多的其他的知识。对于学习angular不利。
下面是一个完整的实例

Dart 语言指南(二)

Dart 语言指南(二)

类 Classes

Dart 是一种面向对象的语言 包含类和基于 mixin 的继承两部分。每个对象是一个类的实例,并且 Object. 是所有类的父类。 基于 mixin 的继承指的是每个类(除了 Object )都只有一个父类,类体还可以在多个类继承中被重用。

要创建一个对象,你可以使用 new 关键词并在其后跟上一个构造函数 . 构造函数可以写成 ClassName或者ClassName.identifier. 比如:

var jsonData = JSON.decode(''{"x":1, "y":2}'');

// Create a Point using Point().
var p1 = new Point(2, 2);

// Create a Point using Point.fromJson().
var p2 = new Point.fromJson(jsonData);

对象拥有由函数和数据组成的成员 (方法 和 实例变量). 当你调用一个方法时,是基于一个对象调用它的:这个方法能够访问该对象的所有方法和数据.

使用一个点 (.) 引用实例变量或方法:

var p = new Point(2, 2);

// Set the value of the instance variable y.
p.y = 3;

// Get the value of y.
assert(p.y == 3);

// Invoke distanceTo() on p.
num distance = p.distanceTo(new Point(4, 4));

使用 ?. 代替 . 来避免当最左操作数为 null 时产生的异常:

// If p is non-null, set its y value to 4.
p?.y = 4;

一些类提供常量构造函数。 要使用常量构造函数创建编译时常数,请使用 const 代替 new:

var p = const ImmutablePoint(2, 2);

构造两个相同的编译时常量导致一个单一的规范的实例:

var a = const ImmutablePoint(1, 1);
var b = const ImmutablePoint(1, 1);

assert(identical(a, b)); // They are the same instance!

在运行时获取一个对象的类型,你可以使用 Object 类的 runtimeType 属性,该属性返回一个 Type 对象.

print(''The type of a is ${a.runtimeType}'');

以下部分讨论如何实现类.

变量实例

声明实例变量:

class Point {
  num x; // Declare instance variable x, initially null.
  num y; // Declare y, initially null.
  num z = 0; // Declare z, initially 0.
}

所有为初始化的实例变量值为 null.

所有实例变量都生成一个隐式的 getter 方法。非最终实例变量也生成一个隐式 setter 方法。更多查看 Getters 和 setters.

class Point {
  num x;
  num y;
}

main() {
  var point = new Point();
  point.x = 4;          // Use the setter method for x.
  assert(point.x == 4); // Use the getter method for x.
  assert(point.y == null); // Values default to null.
}

如果你要在实例变量声明的时候为其初始化值 (而不是通过构造函数或方法),那么当创建实例时就该为其设值,该值在构造函数和其初始化程序列表之前执行.

Constructors

通过创建一个与其类名相同的函数来声明构造函数 (plus, optionally, an additional identifier as described inNamed constructors). 构造函数的最常见形式是生成构造函数,创建一个类的新实例:

class Point {
  num x;
  num y;

  Point(num x, num y) {
    // There''s a better way to do this, stay tuned.
    this.x = x;
    this.y = y;
  }
}

this 关键字引用当前实例.

Note: 只有当命名出现冲突时使用 this. 否则,Dart 风格指南建议不要用 this.

向实例变量分配构造函数的参数是很常见的一种模式,Dart 语法糖让其变得容易:

class Point {
  num x;
  num y;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  Point(this.x, this.y);
}

默认构造函数

如果您没有声明构造函数,则会为您提供默认构造函数。 默认构造函数没有参数,并调用父类中的无参数构造函数。.

构造函数不能继承

子类不会从他们的超类继承构造函数。声明没有构造函数的子类只有默认(无参数,无名称)构造函数.

命名构造函数

使用命名构造函数为类实现多个构造函数或提供额外的声明:

class Point {
  num x;
  num y;

  Point(this.x, this.y);

  // Named constructor
  Point.fromJson(Map json) {
    x = json[''x''];
    y = json[''y''];
  }
}

请记住,构造函数不是继承的,这意味着父类的命名构造函数不会被子类继承。 如果要使用父类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数.

调用父类的非默认构造函数

默认情况下,子类中的构造函数调用超类的未命名的无参数构造函数。 超类的构造函数在构造函数体的起始处被调用。 如果一个 初始化器列表 也被使用,它将在超类被调用之前执行。 总而言之,执行顺序如下:

  1. 初始化程序列表
  2. 父类的无参构造
  3. 主类的无参构造

如果超类没有未命名的无参数构造函数,则必须手动调用超类中的一个构造函数。 在冒号 (:) 之后,在构造函数体(如果有的话)之前指定超类构造函数.

下面的例子中,Employee 类的构造函数调用了其父类 Person 的命名构造函数。点击运行按钮 ( red-run.png ) 执行代码.

class Person {
  String firstName;

  Person.fromJson(Map data) {
    print(''in Person'');
  }
}

class Employee extends Person {
  // Person does not have a default constructor;
  // you must call super.fromJson(data).
  Employee.fromJson(Map data) : super.fromJson(data) {
    print(''in Employee'');
  }
}

main() {
  var emp = new Employee.fromJson({});

  // Prints:
  // in Person
  // in Employee
  if (emp is Person) {
    // Type check
    emp.firstName = ''Bob'';
  }
  (emp as Person).firstName = ''Bob'';
}

因为在调用构造函数之前对父类构造函数的参数进行求值,所以参数可以是一个表达式,例如函数调用:

class Employee extends Person {
  // ...
  Employee() : super.fromJson(findDefaultData());
}

Note: 在构造函数初始化列表中使用 super() 时,将其放在最后。更多信息查看 Dart usage guide.

Warning: 父类的构造函数的参数无权访问 this. 比如,参数能访问静态方法不能访问实例方法.

Initializer list

除了调用超类构造函数之外,还可以在构造函数体运行之前初始化实例变量,用逗号分隔初始化器.

class Point {
  num x;
  num y;

  Point(this.x, this.y);

  // Initializer list sets instance variables before
  // the constructor body runs.
  Point.fromJson(Map jsonMap)
      : x = jsonMap[''x''],
        y = jsonMap[''y''] {
    print(''In Point.fromJson(): ($x, $y)'');
  }
}

Warning: 初始化程序的右侧无法访问 this.

初始化器列表在设置 final 字段时很方便。 以下示例在初始化程序列表中初始化三个 final 字段。 单击运行按钮 ( red-run.png) 执行代码.

import ''dart:math'';

class Point {
  final num x;
  final num y;
  final num distanceFromOrigin;

  Point(x, y)
      : x = x,
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

main() {
  var p = new Point(2, 3);
  print(p.distanceFromOrigin);
}

重定向构造函数

有时,构造函数的唯一目的是重定向到同一个类中的另一个构造函数。 重定向构造函数的正文是空的,构造函数调用出现在冒号(:) 之后.

class Point {
  num x;
  num y;

  // The main constructor for this class.
  Point(this.x, this.y);

  // Delegates to the main constructor.
  Point.alongXAxis(num x) : this(x, 0);
}

常量构造函数

如果您的类生成永远不会更改的对象,则可以使这些对象的编译时常量。 为此,定义一个 const 构造函数,并确保所有实例变量都是 final.

class ImmutablePoint {
  final num x;
  final num y;
  const ImmutablePoint(this.x, this.y);
  static final ImmutablePoint origin =
      const ImmutablePoint(0, 0);
}

Factory 构造函数

当不需要总是创建该类的新实例时,使用 factory 关键字。例如,一个工厂构造函数可能从缓存中返回实例或返回一个子类的实例.

下面的例子演示工厂构造函数如何从缓存中返回对象:

class Logger {
  final String name;
  bool mute = false;

  // _cache is library-private, thanks to the _ in front
  // of its name.
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = new Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) {
      print(msg);
    }
  }
}

Note: 工厂构造函数不能访问 this.

调用工厂构造函数,使用 new 关键字:

var logger = new Logger(''UI'');
logger.log(''Button clicked'');

方法

方法是为对象提供行为的函数.

实例方法

对象上的实例方法可以访问实例变量和 this. 下例中 distanceTo() 方法是一个实例方法的示例:

import ''dart:math'';

class Point {
  num x;
  num y;
  Point(this.x, this.y);

  num distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

Getters and setters

Getters 和 setter 是为对象的属性提供读写访问权限的特殊方法。 回想一下,每个实例变量都有一个隐式的 getter,如果合适的话加一个 setter。 您可以使用 get 和 set 关键字来实现 getter 和 setter 来创建其他属性

class Rectangle {
  num left;
  num top;
  num width;
  num height;

  Rectangle(this.left, this.top, this.width, this.height);

  // Define two calculated properties: right and bottom.
  num get right             => left + width;
      set right(num value)  => left = value - width;
  num get bottom            => top + height;
      set bottom(num value) => top = value - height;
}

main() {
  var rect = new Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}

使用 getter 和 setter,您可以从实例变量开始,稍后用方法包装它们,而不用改变客户端代码.

Note: 如运算符 (++) 以预期的方式工作,无论是否明确定义了 getter. 为了避免任何意外的发生,操作符只调用一次 getter,将其值保存在临时变量中.

抽象方法

实例,getter 和 setter 方法可以是抽象的,定义一个接口,但将其实现交给其他类。 要使方法变成抽象方法,请使用分号 (;) 而不是方法体:

abstract class Doer {
  // ...Define instance variables and methods...

  void doSomething(); // Define an abstract method.
}

class EffectiveDoer extends Doer {
  void doSomething() {
    // ...Provide an implementation, so the method is not abstract here...
  }
}

调用抽象方法会导致运行时错误。.

查看 Abstract classes.

可覆盖的操作符

您可以覆盖下表中显示的运算符。 例如,如果定义 Vector(向量)类,则可以定义一个 + 方法来添加两个向量.

下面是覆盖 + 和 - 操作符的实例:

class Vector {
  final int x;
  final int y;
  const Vector(this.x, this.y);

  /// Overrides + (a + b).
  Vector operator +(Vector v) {
    return new Vector(x + v.x, y + v.y);
  }

  /// Overrides - (a - b).
  Vector operator -(Vector v) {
    return new Vector(x - v.x, y - v.y);
  }
}

main() {
  final v = new Vector(2, 3);
  final w = new Vector(2, 2);

  // v == (2, 3)
  assert(v.x == 2 && v.y == 3);

  // v + w == (4, 5)
  assert((v + w).x == 4 && (v + w).y == 5);

  // v - w == (0, 1)
  assert((v - w).x == 0 && (v - w).y == 1);
}

如果你覆盖 ==, 你也应该覆盖 Object 的 hashCode 的 getter 方法。覆盖 == 和 hashCode 的例子,查看 Implementing map keys.

有关覆盖的更多信息,参阅 Extending a class.

抽象类

使用 abstract 修饰符来定义一个 抽象类 — 一个不能实例化的类。抽象类对于定义接口很有用,通常有一些实现。如果想让抽象类变得可实例化 请使用 factory constructor .

抽象类通常具有 抽象方法. 这是一个声明一个抽象类的例子,它有一个抽象方法:

// This class is declared abstract and thus
// can''t be instantiated.
abstract class AbstractContainer {
  // ...Define constructors, fields, methods...

  void updateChildren(); // Abstract method.
}

以下类不是抽象的,因此即使它定义了一个抽象方法也可以实例化:

class SpecializedContainer extends AbstractContainer {
  // ...Define more constructors, fields, methods...

  void updateChildren() {
    // ...Implement updateChildren()...
  }

  // Abstract method causes a warning but
  // doesn''t prevent instantiation.
  void doSomething();
}

隐式接口

每个类隐式定义一个包含类的所有实例成员以及它实现的任何接口的接口。 如果要创建一个支持 B 类 API 而不继承 B 实现的 A 类,则 A 类应实现 B 接口.

一个类实现一个或多个接口通过在 implements 子句中声明它们,然后提供接口所需的 API 来实现。 例如:

// A person. The implicit interface contains greet().
class Person {
  // 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.
  String greet(who) => ''Hello, $who. I am $_name.'';
}

// An implementation of the Person interface.
class Imposter implements Person {
  // We have to define this, but we don''t use it.
  final _name = "";

  String greet(who) => ''Hi $who. Do you know who I am?'';
}

greetBob(Person person) => person.greet(''bob'');

main() {
  print(greetBob(new Person(''kathy'')));
  print(greetBob(new Imposter()));
}

下面是一个指定一个类实现多个接口的例子:

class Point implements Comparable, Location {
  // ...
}

扩展一个类

使用 extends 关键字创建子类, super 引用父类:

class Television {
  void turnOn() {
    _illuminateDisplay();
    _activateIrSensor();
  }
  // ...
}

class SmartTelevision extends Television {
  void turnOn() {
    super.turnOn();
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
  }
  // ...
}

覆盖成员

子类可以覆盖实例方法,getter 和 setter, 您可以使用 @override 注解来表示您有意覆盖成员:

class SmartTelevision extends Television {
  @override
  void turnOn() {
    // ...
  }
  // ...
}

有时缩小方法参数的类型或保证代码中实例变量是 type safe, 可以使用 covariant 关键字.

noSuchMethod()

为了检测或应对尝试使用不存在的方法或实例变量,你可以复写 noSuchMethod():

class A {
  // Unless you override noSuchMethod, using a
  // non-existent member results in a NoSuchMethodError.
  void noSuchMethod(Invocation mirror) {
    print(''You tried to use a non-existent member:'' +
          ''${mirror.memberName}'');
  }
}

如果你使用 noSuchMethod() 为一个或多个类型实现可能的 getter、setter、方法,你可以使用 @proxy 注解来避免警告:

@proxy
class A {
  void noSuchMethod(Invocation mirror) {
    // ...
  }
}

一种替代 @proxy的方式是,如果在编译时你知道有那些类型,就是类声明实现了的类.

class A implements SomeClass, SomeOtherClass {
  void noSuchMethod(Invocation mirror) {
    // ...
  }
}

了解更多注解信息,查看 Metadata.

枚举类型

枚举类型,通常被称为 enumerations 或 enums, 是用于表示固定数量的常量值的特殊类.

使用枚举

使用 enum 关键字声明一个枚举类型:

enum Color {
  red,
  green,
  blue
}

枚举中的每个值都有一个 index getter, 它返回枚举声明中的值从零的位置开始。 例如,第一个值具有索引 0,第二个值具有索引 1.

assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);

要获取枚举中所有值的列表,使用枚举的 values 常量.

List<Color> colors = Color.values;
assert(colors[2] == Color.blue);

可以在 switch 语句中使用枚举。如果 switch (e) 中的 e 被明确地键入为枚举,那么如果你没有处理所有的枚举值,你会被警告:

enum Color {
  red,
  green,
  blue
}
// ...
Color aColor = Color.blue;
switch (aColor) {
  case Color.red:
    print(''Red as roses!'');
    break;
  case Color.green:
    print(''Green as grass!'');
    break;
  default: // Without this, you see a WARNING.
    print(aColor);  // ''Color.blue''
}

枚举类型具有以下限制:

  • 你不能子类化,混合使用或实现一个枚举.
  • 您不能显式地实例化一个枚举.

更多信息查看 Dart 语言规范.

向类中添加功能:mixins

Mixins 是在多个类层次结构中重用类的代码的一种方式.

要使用 mixin,请使用 with 关键字后跟一个或多个 mixin 名称。 以下示例显示使用 mixins 的两个类:

class Musician extends Performer with Musical {
  // ...
}

class Maestro extends Person
    with Musical, Aggressive, Demented {
  Maestro(String maestroName) {
    name = maestroName;
    canConduct = true;
  }
}

要实现一个 mixin,创建一个扩展 Object 的类,没有声明构造函数,没有调用 super. 例如:

abstract class Musical {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    if (canPlayPiano) {
      print(''Playing piano'');
    } else if (canConduct) {
      print(''Waving hands'');
    } else {
      print(''Humming to self'');
    }
  }
}

Note: 从 1.13 起,Dart VM 已经取消了对 mixin 的两个限制::

  • Mixins 允许从 Object 以外的类扩展.
  • Mixins 可以调用 super().

dart2js 中还不支持这些 “super mixins” , 并且在 Dart 分析器中需要 --supermixin 标志.

更多信息查看 文章 Mixins in Dart.

类变量和方法

使用 static 关键字来实现类范围的变量和方法.

静态变量

静态变量(类变量)对于类范围的状态和常量很有用:

class Color {
  static const red =
      const Color(''red''); // A constant static variable.
  final String name;      // An instance variable.
  const Color(this.name); // A constant constructor.
}

main() {
  assert(Color.red.name == ''red'');
}

直到使用时静态变量才被初始化.

Note: 此页面遵循 风格指南建议 ,优选使用 lowerCamelCase 作为常量名称.

静态方法

静态方法(类方法)不对一个实例进行操作,因此无法访问 this. 例如:

import ''dart:math'';

class Point {
  num x;
  num y;
  Point(this.x, this.y);

  static num distanceBetween(Point a, Point b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
  }
}

main() {
  var a = new Point(2, 2);
  var b = new Point(4, 4);
  var distance = Point.distanceBetween(a, b);
  assert(distance < 2.9 && distance > 2.8);
}

Note: 考虑使用顶级函数,而不是静态方法,用于常用或广泛使用的实用程序和功能.

您可以使用静态方法作为编译时常量。 例如,您可以将静态方法作为参数传递给常量构造函数.

泛型

如果您查看基本数组类型 List 的 API 文档, List, 您将看到类型实际上是 List<E>. <…> 符号将 List 标记为 通用 (或参数化) 类型 — 一个有正规类型参数的类型。按照惯例,类型变量具有单字母名称,例如: E, T, S, K, 和 V.

为什么要用泛型?

因为 Dart 中的类型是可选的,所以您不必使用泛型。但是,您可能希望,由于同样的原因,您可能希望在代码中使用其他类型:types(通用或不通用)可让您记录和注释代码,从而使您的意图更清晰.

例如,如果您打算列出只包含字符串,则可以将其声明为 List<String> (将其作为 “List of string). 这样你,你的同行程序员和你的工具(如 IDE 和 Dart VM 在检查模式下)可以检测到将非字符串分配给列表可能是一个错误。 以下是一个例子:

var names = new List<String>();
names.addAll([''Seth'', ''Kathy'', ''Lars'']);
// ...
names.add(42); // Fails in checked mode (succeeds in production mode).

使用泛型的另一个原因是减少代码重复。泛型让您在多个类型之间共享一个接口和实现,同时仍然利用检查模式和静态分析预警。 例如,假设您创建一个用于缓存对象的接口:

abstract class ObjectCache {
  Object getByKey(String key);
  setByKey(String key, Object value);
}

你发现你想要这个接口的字符串特定版本,所以你创建另一个接口:

abstract class StringCache {
  String getByKey(String key);
  setByKey(String key, String value);
}

接着你想要这个接口的数字特别版本… 于是你有了个主意.

通用类型可以节省您创建所有这些接口的麻烦。 相反,您可以创建一个接受类型参数的单一接口:

abstract class Cache<T> {
  T getByKey(String key);
  setByKey(String key, T value);
}

在此代码中,T 是占位类型。 这是一个占位符,您可以将其视为开发人员稍后将定义的类型.

使用集合字面量

List 和 map 字面量能被参数化。参数化字面量就像你之前见过的字面量一样,除了你在括号之前使用的 <type> (对于 list 集合) 或 <keyTypevalueType> (对于 map 集合) . 当您想要在检查模式下输入警告时,可以使用参数化字面量。 以下是使用类型字面量的示例:

var names = <String>[''Seth'', ''Kathy'', ''Lars''];
var pages = <String, String>{
  ''index.html'': ''Homepage'',
  ''robots.txt'': ''Hints for web robots'',
  ''humans.txt'': ''We are people, not machines''
};

构造函数上使用参数化类型

要在使用构造函数时指定一个或多个类型,请将类型放在类名后面的尖括号 (<...>) . 例如:

var names = new List<String>();
names.addAll([''Seth'', ''Kathy'', ''Lars'']);
var nameSet = new Set<String>.from(names);

下例中创建了一个键为 Integer 类型,值为 View 类型的 map 集合:

var views = new Map<int, View>();

泛型集合及其包含的类型

Dart 泛型类型被 修改 , 意味着会附带类型信息。例如,您可以测试集合的类型,即使在生产模式下:

var names = new List<String>();
names.addAll([''Seth'', ''Kathy'', ''Lars'']);
print(names is List<String>); // true

但是,is 表达式仅检查集合的类型 — 而不是里面的对象。在生产模式下, List<String> 里面可能含有非 String 类型的项。解决方案是检查每一项的类型或使用异常处理程序包裹项操作代码 (查看 Exceptions).

Note: 相比之下,Java 中的泛型使用擦除,这意味着泛型类型参数在运行时被删除。 在 Java 中,您可以测试对象是否为 List,但是不能测试它是否为 List<String>.

限制参数化类型

实现泛型类型时,可能需要限制其参数的类型。 你可以使用 extends 来实现 .

// T must be SomeBaseClass or one of its descendants.
class Foo<T extends SomeBaseClass> {...}

class Extender extends SomeBaseClass {...}

void main() {
  // It''s OK to use SomeBaseClass or any of its subclasses inside <>.
  var someBaseClassFoo = new Foo<SomeBaseClass>();
  var extenderFoo = new Foo<Extender>();

  // It''s also OK to use no <> at all.
  var foo = new Foo();

  // Specifying any non-SomeBaseClass type results in a warning and, in
  // checked mode, a runtime error.
  // var objectFoo = new Foo<Object>();
}

使用泛型方法

最初,Dart 的通用支持仅限于类。 一种较新的语法(称为泛型方法)允许在方法和函数上使用类型参数:

T first<T>(List<T> ts) {
  // ...Do some initial work or error checking, then...
  T tmp = ts[0];
  // ...Do some additional checking or processing...
  return tmp;
}

在 first (<T>) 中的泛型类型参数 允许在多个地方使用参数 T :

  • 函数返回类型 (T).
  • 参数类型 (List<T>).
  • 本地变量 (T tmp).

版本要点: SDK 1.21. 中介绍了泛型方法的新语法。 如果使用泛型方法,请选用 SDK 版本为 1.21 或更高版本.

关于泛型的更多信息,参阅 Dart 中的可选类型 和 使用通用方法.

库及可见性

import 和 library 指令能让你创建模块化和可共享的代码库。库不仅提供 API,而且是一个隐私单位:以下划线(_)开头的标识符只能在库内部显示。 每个 Dart 应用程序都是一个库 , 即使它不使用 library 指令.

库可以使用包分发。参阅 Pub Package and Asset Manager 查看关于 pub 组件的更多信息,软件包管理器包含在 SDK 中.

使用库

使用 import 来指定一个库的命名空间在另外一个库的作用域内被使用.

例如,Dart Web 应用程序通常使用 dart:html 库,可以这样引入:

import ''dart:html'';

import 唯一需要的参数是指定库的 URI. 对于内置库,URI 具有特殊的 dart:scheme。 dart: scheme. 对于其他库,您可以使用文件系统路径或 package: scheme. package: scheme 指定由程序包管理器(如 pub 工具)提供的库。例如:

import ''dart:io'';
import ''package:mylib/mylib.dart'';
import ''package:utils/utils.dart'';

Note: URI 代表统一的资源标识符. URLs(统一资源定位符)是一种常见的 URI.

指定库前缀

如果导入两个库的标识符具有冲突,那么您可以为一个或两个库指定前缀。 例如,如果 library1 和 library2 都有一个 Element 类,那么你可能会有这样的代码:

import ''package:lib1/lib1.dart'';
import ''package:lib2/lib2.dart'' as lib2;
// ...
Element element1 = new Element();           // Uses Element from lib1.
lib2.Element element2 = new lib2.Element(); // Uses Element from lib2.

引入库的一部分

如果您只想使用库的一部分,则可以有选择地导入库。例如:

// Import only foo.
import ''package:lib1/lib1.dart'' show foo;

// Import all names EXCEPT foo.
import ''package:lib2/lib2.dart'' hide foo;

懒加载一个库

延迟加载 (也称为 懒加载) 允许应用程序根据需要加载库,如果需要的话。 以下是您可能会使用延迟加载的情况:

  • 减少应用程序的初始启动时间.
  • 要执行 A / B 测试 - 尝试实现,算法的替代 例如.
  • 加载很少使用的功能,如可选 screens 和 dialogs.

要延迟加载一个库,引用时使用 deferred as.

import ''package:deferred/hello.dart'' deferred as hello;

当需要一个库时,使用库的标识符调用 loadLibrary() .

greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}

在上述代码中,直到库被加载 await 关键字将暂停执行。查看更多关于 async 和 await 的信息,参阅 asynchrony support.

您可以在库中多次调用 loadLibrary() ,而不会出现问题。 该库仅加载一次.

使用延期加载时,请记住以下几点:

  • 延迟库的常量不是导入文件中的常量。 记住,这些常量在加载延迟库之前不存在.
  • 您不能在导入文件中使用延迟库中的类型。 相反,请考虑将接口类型移动到由延迟库和导入文件导入的库中.
  • Dart 隐式地将 loadLibrary() 插入到使用 deferred as namespace定义的命名空间中。loadLibrary() 函数返回一个 Future.

实现库

查看 创建 Library Packages 关于如何实现库包的建议.

异步支持

Dart 具有几种支持异步编程的语言特性。 这些功能最常用的是 async 函数和 await 表达式.

Dart 库充满了返回 Future 或 Stream 对象的函数。 这些功能是异步的: 在设置可能耗时的操作(例如 I / O)后返回,而不等待该操作完成.

当您需要使用由 Future 代表的值时,您有两个选择:

  • 使用 async 和 await
  • 使用 Future API

同样,当您需要从 Stream 获取值时,您有两个选项:

  • 使用 async 和一个 asynchronous for loop (await for)
  • 使用 Stream API

使用 async 和 await 的代码是异步的,但它看起来很像同步代码。 例如,这里有一些使用 await 等待异步功能的结果的代码:

await lookUpVersion()

要使用 await, 代码必须在标记为 async 的函数中:

checkVersion() async {
  var version = await lookUpVersion();
  if (version == expectedVersion) {
    // Do something.
  } else {
    // Do something else.
  }
}

你可以使用 trycatch, 和 finally 处理和清理 await 代码中的错误:

try {
  server = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 4044);
} catch (e) {
  // React to inability to bind to the port...
}

声明异步函数

一个 async function 是一个函数,其主体标有 async 标记。尽管异步功能可能会执行耗时的操作,但是在任何正文执行之前,它将立即返回.

checkVersion() async {
  // ...
}

lookUpVersion() async => /* ... */;

async 关键字添加到函数上使其返回 Future. 例如,考虑这个同步函数,它返回一个 String:

String lookUpVersionSync() => ''1.0.0'';

如果将其更改为异步函数 — 例如,由于将来的实现将会耗费时间 — 返回的值是 Future:

Future<String> lookUpVersion() async => ''1.0.0'';

请注意,该函数的主体不需要使用 Future API。 如有必要,Dart 创建 Future 对象.

结合 Futures 使用 await 表达式

await 表达式具有以下形式:

await expression

你可以在一个异步函数中多次使用 await 表达式。例如,下面的代码等了 3 次函数的结果:

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

await 表达式中,表达式 的值通常是一个 Future; 如果不是,则该值将自动包装在 Future 中。此 Future 对象表示返回对象的承诺. await 表达式 的值是返回的对象. await 表达式使执行暂停,直到该对象可用.

如果 await 不起作用,请确保它处于异步函数中. 例如,应用程序的 main() 函数中使用 awaitmain() 的正文必须标记为 async:

main() async {
  checkVersion();
  print(''In main: version is ${await lookUpVersion()}'');
}

结合 streams 使用异步循环

异步 for 循环具有以下形式:

await for (variable declaration in expression) {
  // Executes each time the stream emits a value.
}

表达式 的值必须具有 Stream 类型。 执行情况如下:

  1. 等待直到 Stream 发出一个值.
  2. 执行 for 循环的主体,将变量设置为该发射值.
  3. 重复 1 和 2,直到 Stream 关闭.

要停止侦听流,您可以使用 break 或 return 语句,该语句突破了 for 循环,并从 Stream 中取消订阅.

如果异步 for 循环不起作用,请确保它处于异步功能 例如,要在应用程序的 main() 函数中使用异步 for 循环 main() 的主体必须标记为 async:

main() async {
  ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  ...
}

有关异步编程的更多信息,请参阅库指南 dart:async . 也可以查看文章 Dart 语言异步支持:阶段 1 和 Dart 语言异步支持:阶段 2, 和 Dart 语言规范.

可调用类

为了让你的 Dart 类像方法一样被调用,请实现 call() 方法.

在下例中, WannabeFunction 类定义了 call () 方法,该函数需要三个字符串并连接它们,用空格分开,并附加感叹号。单击运行按钮 ( red-run.png ) 执行代码.

class WannabeFunction {
  call(String a, String b, String c) => ''$a $b $c!'';
}

main() {
  var wf = new WannabeFunction();
  var out = wf("Hi","there,","gang");
  print(''$out'');
}

更多关于将类像函数一样处理,查看 Dart 中的仿真函数.

隔离

现代网络浏览器甚至可以在移动平台上运行在多核 CPU 上。 为了利用所有这些核心,开发人员传统上使用并发运行的共享内存线程。 然而,共享状态并发是容易出错的,可能导致复杂的代码.

而不是线程,所有 Dart 代码都运行在 isolates 内。每个隔离区都有自己的内存堆,确保没有任何其他隔离区可以访问隔离区的状态.

Typedefs

在 Dart 中,函数是对象,就像字符串和数字是对象一样。typedef 或 function-type alias, 给一个函数类型一个别名,当声明字段和返回类型时,可以使用该名称。 当函数类型分配给变量时。当函数类型分配给变量时,typedef 保留类型信息.

思考下列代码,哪一个没有使用 typedef:

class SortedCollection {
  Function compare;

  SortedCollection(int f(Object a, Object b)) {
    compare = f;
  }
}

 // Initial, broken implementation.
 int sort(Object a, Object b) => 0;

main() {
  SortedCollection coll = new SortedCollection(sort);

  // All we know is that compare is a function,
  // but what type of function?
  assert(coll.compare is Function);
}

当将 f 分配给 compare 时类型信息丢失. f 的类型是 (Object, Object) → int (条件 → 意思是返回), compare 的类型是 Function. 如果我们更改代码以使用显式名称并保留类型信息,那么开发人员和工具都可以使用该信息.

typedef int Compare(Object a, Object b);

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

 // Initial, broken implementation.
 int sort(Object a, Object b) => 0;

main() {
  SortedCollection coll = new SortedCollection(sort);
  assert(coll.compare is Function);
  assert(coll.compare is Compare);
}

Note: 目前,typedef 仅限于功能类型。 我们预计这会改变.

因为 typedef 是简单的别名,它们提供了检查任何函数类型的方法。例如:

typedef int Compare(int a, int b);

int sort(int a, int b) => a - b;

main() {
  assert(sort is Compare); // True!
}

元数据

使用元数据提供有关您的代码的额外信息。 元数据注解以字符 @开始,之后是对编译时常数 (例如 deprecated) 的引用或对常量构造函数的调用.

所有 Dart 代码都有三个注解: @deprecated@override, 和 @proxy. 有关使用 @override 和 @proxy 的示例,请参阅扩展一个类. 以下是使用 @deprecated 注解的例子:

class Television {
  /// _Deprecated: Use [turnOn] instead._
  @deprecated
  void activate() {
    turnOn();
  }

  /// Turns the TV''s power on.
  void turnOn() {
    print(''on!'');
  }
}

您可以定义自己的元数据注解。 下面是一个定义一个 @todo 注解的示例,它需要两个参数

library todo;

class todo {
  final String who;
  final String what;

  const todo(this.who, this.what);
}

以下是使用 @todo 注解的示例:

import ''todo.dart'';

@todo(''seth'', ''make this do something'')
void doSomething() {
  print(''do something'');
}

元数据可以出现在库,类,typedef,类型参数,构造函数,工厂,函数,字段,参数或变量声明之前,以及 import 或 export 指令之前。 您可以使用反射在运行时检索元数据.

注释

Dart 支持单行注释、多行注释、文档注释.

单行注释

单行注释以 // 开头。 Dart 编译器忽略 // 和行尾之间的所有内容.

main() {
  // TODO: refactor into an AbstractLlamaGreetingFactory?
  print(''Welcome to my Llama farm!'');
}

多行注释

多行注释以 /* 开始,以 */ 结尾. Dart 编译器忽略 /* 和 */ 之间的所有内容 (除非注释是文档注释,请参阅下一节). 多行注释可以嵌套.

main() {
  /*
   * This is a lot of work. Consider raising chickens.

  Llama larry = new Llama();
  larry.feed();
  larry.exercise();
  larry.clean();
   */
}

文档注释

文档注释是以 /// 或 /** 开头的多行或单行注释。 在连续行上使用 /// 与多行文档注释具有相同的效果.

在文档注释中,Dart 编译器忽略所有文本,除非它包含在括号中。 使用括号,可以参考类,方法,字段,顶级变量,函数和参数。 括号中的名称在已记录的程序元素的词法范围内得到解决.

以下是有关引用其他类和参数的文档注释的示例:

/// A domesticated South American camelid (Lama glama).
///
/// Andean cultures have used llamas as meat and pack
/// animals since pre-Hispanic times.
class Llama {
  String name;

  /// Feeds your llama [Food].
  ///
  /// The typical llama eats one bale of hay per week.
  void feed(Food food) {
    // ...
  }

  /// Exercises your llama with an [activity] for
  /// [timeLimit] minutes.
  void exercise(Activity activity, int timeLimit) {
    // ...
  }
}

在生成的文档中,[Food] 成为 Food 类的 API 文档的链接.

要解析 Dart 代码并生成 HTML 文档,可以使用 文档生成工具. 有关生成的文档的示例,请参阅 Dart API 文档. 有关如何组织您的注释,请参阅 Dart 文档注解指南.

概要

本页总结了 Dart 语言中常用的功能。 更多的功能正在实施,但我们期望他们不会破坏现有的代码。 更多信息查看 Dart 语言规范 和 有效的 Dart.

要了解有关 Dart 核心库的更多信息,参阅 Dart 图书馆之旅.

今天关于swift 学习资源 - Swift 语言指南swift语言入门的分享就到这里,希望大家有所收获,若想了解更多关于Ajax 学习资源 中外都有、Android|iOS - 学习资源 - 电子书资源、angular 学习资源、Dart 语言指南(二)等相关知识,可以在本站进行查询。

本文标签:

上一篇Swift 个人学习笔记 - 01: A Swift Tour(swift入门)

下一篇苹果公开 Swift 3.1 发布以及 Swift 4 开发时间(swift开发ios)