精华内容
下载资源
问答
  • dart语言java语言As a full-stack developer, I have to switch between several programming languages in my day-to-day business: Java (backend), TypeScript (web dev) and Dart (mobile dev). In this blog ...

    dart语言和java语言

    As a full-stack developer, I have to switch between several programming languages in my day-to-day business: Java (backend), TypeScript (web dev) and Dart (mobile dev). In this blog post, I will try to demonstrate fourteen built-in language constructs in TypeScript and Dart which convinced me to believe that these languages are more sophisticated and flexible than Java. You can already see in the picture above how fluent you can build collections in Dart using conditionals and repetition. These features are called “collection for” and “collection if”. Neat? But there are more. As you could also see, the type information in Dart is preserved at runtime. The check if the variable listOfStrings has the type List<String> works fine at runtime. In contrast, Java has type erasure, which means that generic type parameters are removed at runtime. In Java, you can’t test directly whether a collection is of type List<String>.

    作为全栈开发人员,我必须在日常业务中切换几种编程语言:Java(后端),TypeScript(Web开发)和Dart(移动开发)。 在这篇博客文章中,我将尝试演示TypeScriptDart中的 14种内置语言构造,这使我相信这些语言比Java更复杂和灵活。 您已经在上图中看到了使用条件和重复在Dart中构建收藏集的流利程度。 这些功能称为“收集为”和“收集为”。 整齐? 但是还有更多。 您还可以看到,Dart中的类型信息在运行时保留。 检查变量listOfStrings是否具有类型List<String>在运行时可以正常工作。 相反,Java具有类型擦除 ,这意味着在运行时会删除通用类型参数。 在Java中,您不能直接测试集合的类型是否为List<String>

    After reading this blog post, you will notice that people behind TypeScript and Dart spent much time in language design to make them user-friendly. In this article, we will cover:

    阅读此博客文章后,您会发现TypeScript和Dart背后的人们在语言设计上花费了很多时间,以使其易于使用。 在本文中,我们将介绍:

    • String interpolation

      字符串插值
    • Multiline strings

      多行字符串
    • Parameter properties in constructor

      构造函数中的参数属性
    • Optional parameters

      可选参数
    • Default parameter values

      默认参数值
    • Null-aware operators

      空感知运算符
    • Spread operator

      点差运算符
    • Indistinguishability of fields and getters / setters

      字段和获取器/设置器的不可区分性
    • Mixins (aka multiple inheritance)

      Mixins(又名多重继承)
    • Dynamic extensions of existing types

      现有类型的动态扩展
    • Asynchronous programming with async / await

      异步编程/异步
    • Generators

      发电机
    • Control flow analysis

      控制流分析
    • Method chaining (amazing builder pattern!)

      方法链接(惊人的构建器模式!)

    You can try all code snippets in TypeScript Playground or DartPad respectively.

    您可以分别在TypeScript PlaygroundDartPad中尝试所有代码段。

    1.字符串插值 (1. String interpolation)

    String interpolation is a process of evaluating the final string by injecting a variable or an expression in a string literal.

    字符串插值是通过在字符串文字中注入变量或表达式来评估最终字符串的过程。

    打字稿 (TypeScript)

    The string interpolation is an ECMAScript 2015 (ES6) feature. It works by using${variable} or ${expression} syntax. An example:

    字符串插值是ECMAScript 2015(ES6)功能。 它通过使用${variable}${expression}语法来工作。 一个例子:

    Image for post

    (Dart)

    In Dart, you can use $variable or ${variable} syntax for the string interpolation. The variable itself can be of any type. The expression in ${} can be used as well.

    在Dart中,可以对字符串插值使用$variable${variable}语法。 变量本身可以是任何类型。 ${}的表达式也可以使用。

    Image for post

    Dart internally calls toString() on objects that are being interpolated.

    Dart在要内插的对象上内部调用toString()

    Sure, in Java you can leverage String.format(...) but built-in language constructs in TypeScript and Dart are shorter and more concise.

    当然,在Java中,您可以利用String.format(...)但是TypeScript和Dart中的内置语言结构更短,更简洁。

    2.多行字符串 (2. Multiline strings)

    打字稿 (TypeScript)

    Multiline strings is an ES6 feature. They can be created with a backtick (`) at begin and end of a string. No + sign is necessary for string concatenation.

    多行字符串是ES6的功能。 可以在字符串的开头和结尾使用反引号(`)来创建它们。 字符串连接不需要+号。

    Image for post

    (Dart)

    The Dart’s way to create a multiline string is a triple quote with either single or double quotation marks.

    Dart创建多行字符串的方式是用单引号或双引号引起来的三重引号。

    Image for post

    Furthermore, if you have two string literals, you do not need to use + to concatenate them. Example:

    此外,如果您有两个字符串文字,则无需使用+来串联它们。 例:

    Image for post

    3.构造函数中的参数属性 (3. Parameter properties in constructors)

    Parameter properties in constructors let you create and initialize a class member in one place.

    构造函数中的参数属性使您可以在一处创建和初始化类成员。

    打字稿 (TypeScript)

    Parameter properties are declared by prefixing a constructor parameter with an accessibility modifier or readonly, or both. For example, instead of

    通过使用可访问性修饰符或readonly或两者都为构造函数参数加上前缀来声明参数属性。 例如,代替

    Image for post

    just write

    写就好了

    Image for post

    (Dart)

    In Dart, this feature is called “initializing formals”. Just use the this. syntax before a constructor parameter. The main rule of effective Dart is: do use initializing formals when possible.

    在Dart中,此功能称为“初始化形式”。 只需使用this. 构造函数参数之前的语法。 有效Dart的主要规则是:尽可能使用初始化形式。

    Image for post

    Note that in Dart you can not omit the property declaration (see the code snippet above). But in Dart you can use ; instead empty constructor body{}.

    请注意,在Dart中,您不能省略属性声明(请参见上面的代码段)。 但是在Dart中你可以使用; 而是使用空的构造函数主体{}

    Saidy, but this simple and handy feature is missing completely in Java.

    Saidy,但是此简单易用的功能在Java中完全缺失。

    4.可选参数 (4. Optional parameters)

    Optional parameters are optional in that the caller isn’t required to specify a value for the parameter when calling a function.

    可选参数是可选的,因为在调用函数时不需要调用者为参数指定值。

    打字稿 (TypeScript)

    In TypeScript, we can specify that a property (in interfaces / classes) or a parameter (in functions) is optional with a question mark (?) after the name. Optional parameters are especially handy in functions. An example:

    在TypeScript中,我们可以指定属性(在接口/类中)或参数(在函数中)是可选的,名称后带有问号(?)。 可选参数在功能上特别方便。 一个例子:

    Image for post

    (Dart)

    Optional parameters in Dart can be named and positional. A parameter wrapped by [ ] is a positional optional parameter. A parameter wrapped by { } is a named optional parameter. Named parameters can be referenced by names when invoking a function. Values for named parameters can be passed in any order, when invoking the function (this is the main benefit of them). The required parameters are listed first, followed by any optional parameters.

    Dart中的可选参数可以命名为 positional[ ]包裹的参数是位置可选参数。 由{ }包裹的参数是命名的可选参数。 调用函数时,可以通过名称引用命名参数。 调用函数时,可以按任何顺序传递命名参数的值(这是它们的主要优点)。 首先列出必需的参数,然后列出所有可选参数。

    Image for post

    5.默认参数值 (5. Default parameter values)

    An optional parameter can have a default value which is used when a caller does not specify a value. Such default values are provided after the = operator.

    可选参数可以具有默认值,该默认值在调用方未指定值时使用。 此类默认值在=运算符之后提供。

    打字稿 (TypeScript)

    The TypeScript example above can be rewritten now as

    上面的TypeScript示例现在可以重写为

    Image for post

    The function invocation at the default value’s position can be placed as well. By this way, the default value can be calculated at runtime.

    也可以将函数调用放在默认值的位置。 通过这种方式,可以在运行时计算默认值。

    (Dart)

    The example with the optional parameter port can be rewritten as

    带有可选参数port的示例可以重写为

    Image for post

    6.空感知运算符 (6. Null-aware operators)

    There are two null-aware operators which work almost similar in TypeScript and Dart and allow us to write a compact code.

    有两个null感知运算符,它们在TypeScript和Dart中的工作原理几乎相似,并允许我们编写紧凑的代码。

    • Optional chaining operator ?.

      可选的链接运算符?.

    • The logical nullish coalescing operator ??

      逻辑无效合并运算符??

    打字稿 (TypeScript)

    The optional chaining and nullish coalescing operators are new ECMAScript features. Optional chaining lets us write code where TypeScript can immediately stop running some expressions if we run into a null or undefined. Let's write a code snippet with and without the optional chaining operator.

    可选的链接和无效合并运算符是ECMAScript的新功能。 可选的链接使我们可以编写代码,如果遇到nullundefined ,TypeScript可以立即停止运行某些表达式。 让我们编写一个带有和不带有可选链接运算符的代码段。

    Image for post

    The nullish coalescing operator returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand. For example:

    当空的合并运算符的左侧操作数为nullundefined ,将返回其右侧操作数,否则返回其左侧操作数。 例如:

    Image for post

    This is a new way to say that the value foo will be used when it's "present"; but when it's null or undefined, calculate bar() in its place. The above code is equivalent to

    这是一种新的方式来表示值foo将在“存在”时使用; 但是当它为nullundefined ,请在其位置计算bar() 。 上面的代码相当于

    Image for post

    (Dart)

    In Dart, alle properties and variables are initialized with null per default (every type is an object). Use ?. when you want to call a method or access a property on an nullable object. If the object is null, the result of the method invocation or property accessing is also null. The syntax with the null-aware ?? operator is expr = expr1 ?? expr2. If expr1 is non-null, returns its value; otherwise, evaluates and returns the value of expr2. With null-aware operators you can do nice things like this one:

    在Dart中,默认情况下alle属性和变量初始化为null (每种类型都是一个对象)。 使用?. 当您要调用方法或访问可为空的对象上的属性时。 如果对象为null ,则方法调用或属性访问的结果也为null 。 具有null感知的语法?? 运算符是expr = expr1 ?? expr2 expr = expr1 ?? expr2 如果expr1不为null,则返回其值; expr1 ,返回0。 否则,求值并返回expr2的值。 使用了解空值的运算符,您可以执行以下操作:

    Image for post

    7.点差运算符 (7. Spread operator)

    The syntax of the spread operator is three dots (...) followed by an iterable object. It expands the iterable object into individual elements.

    扩展运算符的语法是三个点( ... ),后跟一个可迭代的对象。 它将可迭代对象扩展为单个元素。

    打字稿 (TypeScript)

    The spread operator can be used to expand an array in a places where zero or more elements are expected. Using this, we can e.g. merge two or more arrays or objects. Examples:

    散布运算符可用于在期望零个或多个元素的地方扩展数组。 使用此方法,我们可以例如合并两个或多个数组或对象。 例子:

    Image for post

    (Dart)

    The spread operator in Dart provides a concise way to insert multiple elements into a collection. You can use this operator to insert all elements of a collection into another collection. There is also a null-aware spread operator ...? which helps to avoid exceptions when to be inserted collection is null.

    Dart中的传播运算符提供了一种简洁的方法,可以将多个元素插入到集合中。 您可以使用此运算符将一个集合的所有元素插入另一个集合。 还有一个空感知的传播算子...? 这有助于避免在插入collection时为null异常。

    Image for post

    8.字段和获取器/设置器的不可区分性 (8. Indistinguishability of fields and getters / setters)

    Getters and setters provide access to the properties of an object. In Java, it’s common to hide all fields behind getters and setters, even if the implementation just forwards to the field. Calling a getter method is different than accessing a field in Java. Getters and setters have different names than the corresponding field names. For example, if you have a field name, the getter would be getName() and the setter setName(String name). Just look at this example in Java:

    使用Getter和Setter可以访问对象的属性。 在Java中,通常将所有字段隐藏在getter和setter后面,即使实现只是转发到该字段也是如此。 调用getter方法与访问Java中的字段不同。 获取器和设置器的名称与对应的字段名称不同。 例如,如果您有一个字段name ,则getter将是getName() ,而设置方法是setName(String name) 。 只要看一下Java中的这个例子:

    Image for post

    In TypeScript and Dart, the getters and setters have the same names as the corresponding fields. You can expose a field in a class and later wrap it in a getter and setter without having to touch any code that uses that field. We can say — fields and getters / setters are completely indistinguishable. Let’s look at code snippets in these languages.

    在TypeScript和Dart中,getter和setter的名称与相应字段的名称相同。 您可以在一个类中公开一个字段,然后将其包装在一个getter和setter中,而无需触摸任何使用该字段的代码。 我们可以说-字段和获取器/设置器是完全无法区分的。 让我们看一下这些语言的代码片段。

    打字稿 (TypeScript)

    Image for post

    Please note, you don’t have to use the method here, just assign the value directly.

    请注意,您不必在这里使用方法,只需直接分配值即可。

    (Dart)

    Image for post

    Effective Dart recommends: DON’T wrap a field in a getter and setter unnecessarily.

    有效的Dart建议:不要将字段不必要地包装在getter和setter中。

    9. Mixins (9. Mixins)

    Mixin is the process of combining multiple classes to a single target class. It is intended to overcome the limitations of single inheritance model. In Java, TypeScript an Dart, we can’t inherit or extend from more than one class with extends but mixins in TypeScript and Dart helps us to get around that. Mixins create partial classes which we can combine to form a single class that contains all the methods and properties from the partial classes. From a mathematical point of view, one can say that the classic, single super-class inheritance creates a tree (left picture). And mixin pattern creates a directed acyclic graph (right picture).

    Mixin是将多个类组合为单个目标类的过程。 旨在克服单一继承模型的局限性。 在Java中,打字稿的Dart,我们不能继承或一个以上的类扩展与extends ,但在打字稿及Dart混入帮助我们要解决这个问题。 Mixins创建子类,我们可以将它们组合成一个单独的类,其中包含子类中的所有方法和属性。 从数学的角度来看,可以说经典的单一超类继承创建了一棵树(左图)。 mixin模式创建有向无环图(右图)。

    Image for post

    Composing partial behaviors with mixins in both languages is different.

    用两种语言的mixins构成部分行为是不同的。

    打字稿 (TypeScript)

    Let’s create a Timestamped mixin that tracks the creation date of an object in a timestamp property:

    让我们创建一个带有Timestamped mixin,它在timestamp属性中跟踪对象的创建日期:

    Image for post

    Let’s create a User class now.

    现在创建一个User类。

    Image for post

    Finally, we create a new class by mixing Timestamped into User.

    最后,我们通过将Timestamped混合到User创建一个新类。

    Image for post

    (Dart)

    In Dart, we can use the with keyword on every class we want to extend with additional properties and behaviors. Assume, we have a class Person.

    在Dart中,我们可以在每个要扩展的类上使用with关键字,并附加其他属性和行为。 假设我们有一个Person类。

    Image for post

    Let’s define a class Learner having one method learn() and a class Student which will extend Person and include everything from theLearner.

    让我们定义一个具有一个方法learn() Learner类和一个将扩展Person并包括该Learner所有内容的Student类。

    Image for post

    An instance of type Student can now access both methods info() (from Person) and learn() (from Learner).

    现在,类型为Student的实例可以访问info() (来自Person )和learn() (来自Learner )这两种方法。

    Image for post

    10.现有类型的动态扩展 (10. Dynamic extensions of existing types)

    Dynamic extensions are a way to add additional functionality to existing libraries without touching them. That means, if you have e.g. a class in a third-party library, you can extend it without changing the class or creating a subclass. This is a killer feature in my opinion which makes a language attractive. There is no something similar in Java at the time of writing.

    动态扩展是一种在不影响现有库的情况下向其添加其他功能的方法。 这意味着,如果您在第三方库中有一个类,则可以在不更改该类或创建子类的情况下对其进行扩展。 我认为这是一项杀手级功能,使一种语言更具吸引力。 撰写本文时,Java中没有类似的东西。

    打字稿 (TypeScript)

    TypeScript allows merging between multiple types such as interface with interface, enum with enum, namespace with namespace. This feature is called declaration merging. Declaration merging is when the TypeScript complier merges two or more types into one declaration provided the same name. Example:

    TypeScript允许在多个类型之间进行合并,例如interfaceinterfaceenumenumnamespacenamespace 。 此功能称为声明合并 。 声明合并是指TypeScript编译器将两个或多个类型合并为一个提供相同名称的声明。 例:

    Image for post

    Why use declaration merging and where does it shine?

    为什么要使用声明合并,它在哪里发光?

    • You can extend declarations of third-party libraries that you import into your project.

      您可以扩展导入到项目中的第三方库的声明。
    • You can extend declarations of generated TypeScipt definitions, which are usually coming from backend. In my project, we generate TypeScript code from plain Java objects by a Maven plugin.

      您可以扩展生成的TypeScipt定义的声明,这些声明通常来自后端。 在我的项目中,我们通过Maven插件从普通Java对象生成TypeScript代码。
    • TypeScript uses merging to get different types for the different versions of JavaScript’s standrad libraries. Example: the Array interface. It is defined in lib.es5.d.ts file. By default this is all you get. But if you add ES2015 to the lib entry of your tsconfig.json, TypeScript will also include lib.es2015.d.ts. This includes another Array interface with additional methods like find that were added in ES2015. They get added to the other Array interface via merging.

      TypeScript使用合并为JavaScript的不同版本的standrad库获取不同的类型。 示例: Array接口。 它在lib.es5.d.ts文件中定义。 默认情况下,这就是您所获得的。 但是,如果你添加ES2015tsconfig.jsonlib项,输出文件也包括lib.es2015.d.ts。 这包括另一个Array接口,以及ES2015中添加的其他方法(如find 。 通过合并将它们添加到另一个Array接口。

    One project where I was involved and used this technique: OffscreenCanvas by “Definitely Typed” — the repository for high quality TypeScript type definitions.

    我参与并使用了该技术的一个项目: “ Definitely Typed”的OffscreenCanvas-高质量TypeScript类型定义的存储库。

    (Dart)

    In Dart there is also a way to add functionality to existing libraries. This feature is called extension methods. The syntax is extension [<Name>] on <Type> {<Methods>}. The name after the keyword extension is optional. Let’s see some examples how to extend the type int.

    在Dart中,还有一种向现有库添加功能的方法。 此功能称为扩展方法 。 语法是extension [<Name>] on <Type> {<Methods>} 。 关键字extension名后的名称是可选的。 让我们看一些如何扩展int类型的示例。

    Image for post

    Now, we can directly call toBinaryString() on every integer. There are two implementations of the method str() — in this case, we should wrap an integer by the extension name to enables the unambiguous identification of the extension.

    现在,我们可以直接在每个整数上调用toBinaryString() 。 方法str()有两种实现-在这种情况下,我们应该在扩展名旁边包装一个整数,以实现对扩展的明确标识。

    Image for post

    Let’s see another example how to extend a generic List.

    让我们看另一个示例,如何扩展通用List

    Image for post

    11.异步编程/异步 (11. Asynchronous programming with async / await)

    A long time ago, an asynchronous behavior was modeled using callbacks. Having many nested callbacks led to so called callback hell or pyramid of doom. An example (pseudo code):

    很久以前,异步行为是使用回调建模的。 有许多嵌套的回调导致所谓的回调地狱毁灭金字塔 。 一个例子(伪代码):

    Image for post

    Problems with callbacks:

    回调问题:

    • Execution order is the opposite of the code order.

      执行顺序与代码顺序相反。
    • The code is hard to read.

      该代码很难阅读。
    • Difficult to run requests in parallel.

      难以并行运行请求。

    Later, many programming languages introduced much better concepts to deal with asynchronism. JavaScript introduced the concept of a Promise to break the pyramid of doom. A Promise represent something that will be available in the future. Dart has the concept of Future. A Future represents the result of an asynchronous operation. It is waiting for the function’s asynchronous operation to finish or to throw an error. If the asynchronous operation succeeds, the Future completes with a value.

    后来,许多编程语言引入了更好的概念来处理异步性。 JavaScript引入了Promise的概念来打破厄运金字塔。 一个Promise代表将来会可用的东西。 Dart具有Future的概念。 Future表示异步操作的结果。 它正在等待函数的异步操作完成或引发错误。 如果异步操作成功,则Future将以一个值完成。

    What is about Java? Since Java 8 we have CompletableFuture. An example:

    什么是Java? 从Java 8开始,我们有了CompletableFuture 。 一个例子:

    Image for post

    The get method waits for the computation to complete, and then retrieves its result. Can we write this kind of code better? Yes, in TypeScript and Dart we can write it better with async and await.

    get方法等待计算完成,然后检索其结果。 我们可以更好地编写这种代码吗? 是的,在TypeScript和Dart中,我们可以使用asyncawait更好地编写它。

    打字稿 (TypeScript)

    ES2017 introduced the async and await keywords which allow to write the code in a synchronous manner. Anawait is used to wait for a promise to resolve or reject. It can only be used inside an async function. Let’s rewrite the psedo-code above.

    ES2017引入了asyncawait关键字,这些关键字允许以同步方式编写代码。 await用于等待承诺解决或拒绝。 它只能在async函数中使用。 让我们重写上面的psedo代码。

    Image for post

    The await keywords pause execution of the fetchPages function until each Promise returned by fetch resolves.

    关键字await暂停fetchPages函数的执行,直到fetch返回的每个Promise都解析为止。

    (Dart)

    Thanks to Dart’s feature async / await, you might never need to use the Future API directly. So, instead of

    由于Dart具有async / await功能,您可能永远不需要直接使用Future API。 所以,代替

    Image for post

    you can write the code more straightforward

    您可以更直接地编写代码

    Image for post

    If you follow Dart’s best practice, the return value should be Future<void>.

    如果您遵循Dart的最佳做法,则返回值应为Future<void>

    12.发电机 (12. Generators)

    Generators (more precisely generator functions) is a handy construct when you need to lazily produce a sequence of values. Both TypeScript and Dart have a built-in support of synchronous and asynchronous generators. With generators, we can create iterable objects where values come synchronously or asynchronously. A generator function is declared with an asterisk (*). A produced sequence of values is emitted with the yield keyword. In this blog post, I will only show how to use asynchronous generators.

    当您需要延迟生成值序列时, 生成器 ( 确切地说是 生成器函数 )是一种方便的构造。 TypeScript和Dart都具有对同步生成器和异步生成器的内置支持。 使用生成器,我们可以创建可迭代对象,其中值同步或异步出现。 生成器函数用星号(*)声明。 产生的值序列与yield关键字一起发出。 在此博客文章中,我将仅展示如何使用异步生成器。

    打字稿 (TypeScript)

    If we execute a generator function, an object implementing iterable protocol is returned. The iterable protocol allows an object to be iterable. To iterate over such objects, we should use for … of or for await … of loop respectively. An asynchronous generator is an async function with asterisk. The function body contains one or more await operators. The await operator is used to wait for a promise to resolve or reject.

    如果执行生成器函数,则返回实现可迭代协议的对象。 可迭代协议允许对象可迭代。 要遍历此类对象,我们应该分别使用for … offor await … of循环。 异步生成器是带有星号的async函数。 函数主体包含一个或多个await操作符。 等待操作符用于等待承诺解决或拒绝。

    Image for post

    (Dart)

    Dart has a similar concept as TypeScript. To implement an asynchronous generator function, mark the function body as async*, and use yield statements to deliver values. The return value is a Stream object.

    Dart与TypeScript具有相似的概念。 要实现异步生成器函数,请将函数主体标记为async* ,并使用yield语句传递值。 返回值是一个Stream对象。

    Image for post

    13.控制流分析 (13. Control flow analysis)

    Both TypeScript and Dart have an excellent support for control flow analysis. The type checker analyses all possible flows of control in statements and expressions to produce the most specific type possible at any given location for a local variable or parameter. Let’s create three classes Pet, Dog and Cat in order to demonstrate the control flow analysis.

    TypeScript和Dart都对控件流分析提供了出色的支持。 类型检查器分析语句和表达式中所有可能的控制流,以在任何给定位置为局部变量或参数生成最具体的类型 。 让我们创建三个类PetDogCat ,以演示控制流分析。

    Image for post

    打字稿 (TypeScript)

    In TypeScript, you can create user defined type guards. User defined type guard is just a function that returns a type predicate in the form of someArgument is someType. If the function returns true, TypeScript will narrow the type, so that no cast is required.

    在TypeScript中,您可以创建用户定义的类型Guard 。 用户定义的类型保护只是一个以someArgument is someType形式返回类型谓词的函数。 如果函数返回true ,则TypeScript将缩小类型,因此不需要强制转换。

    Image for post

    As you can see, in the if-statement, we can call bark() without the cast to the Dog. The type of the foo was narrowed automatically by the TypeScript compiler.

    如您所见,在if语句中,我们可以在不强制转换为Dog情况下调用bark()foo的类型由TypeScript编译器自动缩小。

    (Dart)

    To achieve the same result in Dart, we can use the type test operator is. It returns true if the object has the specified type.

    为了在Dart中获得相同的结果,我们可以使用类型测试运算符is 。 如果对象具有指定的类型,则返回true

    Image for post

    The Dart compiler narrows the type of the foo without the typecast as (as operator is used to cast an object to a particular type).

    Dart编译器将foo的类型缩小为没有类型转换as ( as运算符将对象转换为特定类型)。

    14.方法链接 (14. Method chaining)

    Method chaining allows you to apply a sequence of operations on the same object. Method chaining is often being used for building objects for classes having a lot of properties. A standard implementation of this approach in OOP languages is a builder pattern. Let’s implement a simple example in Java.

    方法链接允许您对同一对象应用一系列操作。 方法链接通常用于为具有很多属性的类构建对象。 在OOP语言中这种方法的标准实现是构建器模式 。 让我们用Java实现一个简单的例子。

    Image for post

    By returning this, we can receive the class instance back immediately to call another method in the chain. There is a lot of code, even for this simple implementation without an inner public staticBuilder class (a popular implementation of the builder pattern). TypeScript and Dart can save your time and offer more elegant constructs here.

    通过返回this ,我们可以立即收到类实例,以调用链中的另一个方法。 即使没有这种简单的实现,也有很多代码,而没有内部公共静态Builder类( Builder器模式的流行实现)。 TypeScript和Dart可以节省您的时间,并在此处提供更优雅的构造。

    打字稿 (TypeScript)

    I like an implementation of the builder pattern with ES6 proxy. The Proxy object enables you to create a proxy for another object, which can intercept and redefine operations for that object. See an explanation for more details. A generic implementation for every use case could be as follows:

    我喜欢用ES6代理实现构建器模式。 Proxy对象使您可以为另一个对象创建代理,该代理可以拦截和重新定义该对象的操作。 有关更多详细信息,请参见说明 。 每个用例的通用实现如下:

    Image for post

    The usage is simple. For example:

    用法很简单。 例如:

    Image for post

    For more advanced generic implementation look this project on GitHub.

    有关更高级的通用实现,请在GitHub上查看此项目

    (Dart)

    Dart has a cascaded method invocation. Instead of . notation, the cascade notation uses .. (double-dot) in order to access current modifying instance. Assume, we have a class User with setters / getters for most important fields. We can instantiate a User instance as follows with the cascaded method invocation:

    Dart具有级联方法调用。 代替. 表示法,级联表示法使用.. (双点)来访问当前的修​​改实例。 假设,我们有一个User类,其中包含最重要字段的setters / getters。 我们可以使用级联方法调用实例化User实例,如下所示:

    Image for post

    By using cascade, we don’t have to put many of repeated return this inside the class. But we can still return something else appropriate to the methods. Cascades can be nested as well. That allows even faster object buildings. See the example with nested cascades from the Dart language tour. This feature saves you the steps of creating temporary variables and allows you to write more fluid code.

    通过使用层叠,我们不必在类中放入许多重复的return this 。 但是我们仍然可以返回适合该方法的其他内容。 级联也可以嵌套。 这样可以更快地建立对象。 请参阅Dart语言教程中有关嵌套级联示例 。 此功能节省了创建临时变量的步骤,并允许您编写更多流畅的代码。

    That’s all. Stay tuned!

    就这样。 敬请关注!

    翻译自: https://medium.com/@OlegVaraksin/14-language-features-in-typescript-and-dart-you-may-miss-in-java-6bdc11c6fee7

    dart语言和java语言

    展开全文
  • Doing some consulting work for a bigger German companies Future Technologies Group I have ported about 6000 lines of Java server side software to Dart. This should help to answer the question whether ...

    Doing some consulting work for a bigger German companies Future Technologies Group I have ported about 6000 lines of Java server side software to Dart. This should help to answer the question whether Dart can efficiently be used on the server. (Which itself would give a green light for Dart due to the searched for advantage of having one language for client and server side programming.)

    Learning about Dart (which I really enjoyed working with) gave me an expectation of a performance penalty of 30-50% relative to Java but in any case no worse than 100% (twice as slow) which is the cutoff for the decision process mentioned above.

    The port went smoothly. I learned a lot. Unit tests were fine. But the performance turned out to be extremly bad ... SEVEN times slower overall compared to the Java program.

    Profiling the code revealed two main culprits: data conversion and file I/O. Maybe I'm doing something wrong? Before I go back to my client and they cancel their Dart research I would like to search some advice on how to improve things. Let's start with data conversion, the conversion of native Dart data types into various binary formats which can be used for effective transfer and storage of data.

    Usually these conversions are simple and very fast because nothing has really to be converted from the used internal format but mostly stored into a buffer. I created a benchmark program which somehow reflects the typical use of these conversions in my program:

    import 'dart:typed_data';

    import 'package:benchmark_harness/benchmark_harness.dart';

    // Create a new benchmark by extending BenchmarkBase

    class ConversionBenchmark extends BenchmarkBase {

    Uint8List result;

    ConversionBenchmark() : super("Conversion");

    // The benchmark code.

    void run() {

    const int BufSize = 262144; // 256kBytes

    const int SetSize = 64; // one "typical" set of data, gets repeated

    ByteData buffer = new ByteData(BufSize);

    double doubleContent = 0.0; // used to simulate double content

    int intContent = 0; // used to simulate int content

    int offset = 0;

    for (int j = 0; j < buffer.lengthInBytes / SetSize; j++) {

    // The following represents some "typical" conversion mix:

    buffer.setFloat64(offset, doubleContent); offset += 8; doubleContent += 0.123;

    for (int k = 0; k < 8; k++) { // main use case

    buffer.setFloat32(offset, doubleContent); offset += 4; doubleContent += 0.123;

    }

    buffer.setInt32(offset, intContent); offset += 4; intContent++;

    buffer.setInt32(offset, intContent); offset += 4; intContent++;

    buffer.setInt16(offset, intContent); offset += 2; intContent++;

    buffer.setInt16(offset, intContent); offset += 2; intContent++;

    buffer.setInt8(offset, intContent); offset += 1; intContent++;

    buffer.setInt8(offset, intContent); offset += 1; intContent++;

    buffer.buffer.asUint8List(offset).setAll(0, "AsciiStrng".codeUnits); offset += 10;

    // [ByteData] knows no other mechanism to transfer ASCII strings in

    assert((offset % SetSize) == 0); // ensure the example content fits [SetSize] bytes

    }

    result = buffer.buffer.asUint8List(); // only this can be used for further processing

    }

    }

    main() {

    new ConversionBenchmark().report();

    }

    It is based on the benchmark harness from https://github.com/dart-lang/benchmark_harness. For comparisions I used the following Java program based on a port of the Dart benchmark harness from https://github.com/bono8106/benchmark_harness_java:

    package ylib.tools;

    import java.nio.ByteBuffer;

    public class ConversionBenchmark extends BenchmarkBase {

    public ByteBuffer result;

    public ConversionBenchmark() { super("Conversion"); }

    // The benchmark code.

    @Override protected void run() {

    final int BufSize = 262144; // 256kBytes

    final int SetSize = 64; // one "typical" set of data, gets repeated

    ByteBuffer buffer = ByteBuffer.allocate(BufSize);

    double doubleContent = 0.0; // used to simulate double content

    int intContent = 0; // used to simulate int content

    for (int j = 0; j < (buffer.capacity() / SetSize); j++) {

    // The following represents some "typical" conversion mix:

    buffer.putDouble(doubleContent); doubleContent += 0.123;

    for (int k = 0; k < 8; k++) { // main use case

    buffer.putFloat((float)doubleContent); doubleContent += 0.123;

    }

    buffer.putInt(intContent); intContent++;

    buffer.putInt(intContent); intContent++;

    buffer.putShort((short)intContent); intContent++;

    buffer.putShort((short)intContent); intContent++;

    buffer.put((byte)intContent); intContent++;

    buffer.put((byte)intContent); intContent++;

    buffer.put("AsciiStrng".getBytes());

    //assert((buffer.position() % SetSize) == 0); // ensure the example content fits [SetSize] bytes

    }

    buffer.flip(); // needed for further processing

    result = buffer; // to avoid the compiler optimizing away everything

    }

    public static void main(String[] args) {

    new ConversionBenchmark().report();

    }

    }

    The Java code runs almost exactly 10 times faster than the Dart code on my Intel Windows 7 machine. Both run in production mode on their respective VMs.

    Is there an obvious error in the code? Or are there different Dart classes available to do the job? Any explanation as to why Dart is so much slower with these simple conversions? Or do I have completely wrong expectations with respect to Dart VM performance?

    解决方案

    It is true that performance of byte data methods (ByteData.setXYZ and ByteData.getXYZ) is pretty bad on Dart VM compared to direct typed array access. We started working on the issue and initial results are promising[1].

    In the mean time you can work around this unfortunate performance regression by rolling your own conversion to big endian using typed arrays (full code at[2]):

    /// Writer wraps a fixed size Uint8List and writes values into it using

    /// big-endian byte order.

    class Writer {

    /// Output buffer.

    final Uint8List out;

    /// Current position within [out].

    var position = 0;

    Writer._create(this.out);

    factory Writer(size) {

    final out = new Uint8List(size);

    if (Endianness.HOST_ENDIAN == Endianness.LITTLE_ENDIAN) {

    return new _WriterForLEHost._create(out);

    } else {

    return new _WriterForBEHost._create(out);

    }

    }

    writeFloat64(double v);

    }

    /// Lists used for data convertion (alias each other).

    final Uint8List _convU8 = new Uint8List(8);

    final Float32List _convF32 = new Float32List.view(_convU8.buffer);

    final Float64List _convF64 = new Float64List.view(_convU8.buffer);

    /// Writer used on little-endian host.

    class _WriterForLEHost extends Writer {

    _WriterForLEHost._create(out) : super._create(out);

    writeFloat64(double v) {

    _convF64[0] = v;

    out[position + 7] = _convU8[0];

    out[position + 6] = _convU8[1];

    out[position + 5] = _convU8[2];

    out[position + 4] = _convU8[3];

    out[position + 3] = _convU8[4];

    out[position + 2] = _convU8[5];

    out[position + 1] = _convU8[6];

    out[position + 0] = _convU8[7];

    position += 8;

    }

    }

    Benchmarking this manual conversion on your test yields around 6x improvement:

    import 'dart:typed_data';

    import 'package:benchmark_harness/benchmark_harness.dart';

    import 'writer.dart';

    class ConversionBenchmarkManual extends BenchmarkBase {

    Uint8List result;

    ConversionBenchmarkManual() : super("Conversion (MANUAL)");

    // The benchmark code.

    void run() {

    const int BufSize = 262144; // 256kBytes

    const int SetSize = 64; // one "typical" set of data, gets repeated

    final w = new Writer(BufSize);

    double doubleContent = 0.0; // used to simulate double content

    int intContent = 0; // used to simulate int content

    int offset = 0;

    for (int j = 0; j < (BufSize / SetSize); j++) {

    // The following represents some "typical" conversion mix:

    w.writeFloat64(doubleContent); doubleContent += 0.123;

    for (int k = 0; k < 8; k++) { // main use case

    w.writeFloat32(doubleContent); doubleContent += 0.123;

    }

    w.writeInt32(intContent); intContent++;

    w.writeInt32(intContent); intContent++;

    w.writeInt16(intContent); intContent++;

    w.writeInt16(intContent); intContent++;

    w.writeInt8(intContent); intContent++;

    w.writeInt8(intContent); intContent++;

    w.writeString("AsciiStrng");

    assert((offset % SetSize) == 0); // ensure the example content fits [SetSize] bytes

    }

    result = w.out; // only this can be used for further processing

    }

    }

    展开全文
  • 关于DartGolang

    万次阅读 2013-12-14 11:16:31
    关于DartGolang在chrome浏览器中嵌入一个Dart虚拟机,可以用Dart语言开发Web APP。虽然Dart声称通过Dart2JS可以编译成纯JS文件可运行在各个浏览器商,但一个Hello world的JS编译就让人成了笑话。但不排除未来的...

    关于Dart与Golang


    在chrome浏览器中嵌入一个Dart虚拟机,可以用Dart语言开发Web APP。虽然Dart声称通过Dart2JS可以编译成纯JS文件可运行在各个浏览器商,但一个Hello world的JS编译就让人成了笑话。但不排除未来的精进优化,要知道Dart的负责人是V8引擎负责人,V8是Chrome浏览器中的JS引擎,这是一款优秀的速度闪电的JS引擎,所以Dart JS技术的优化精进似乎不是问题。



    Dart更像JAVA。而JAVA要么通过J2SE运行在操作系统桌面上,要么通过J2EE运行在服务器上,要么通过J2ME运行在手机上,还没有JAVA运行在浏览器中(早期Applet不说)。从语法复杂性来说,我个人的感受是Dart不亚于JAVA。


    现在Android手机本地App用JAVA开发和C++开发。Android也和Chrome book正在融合。如果把Chrome就当作Android的桌面,Chrome 也有App Store。用Dart开发Chrome Web App,在Android上运行,也就看不出到底是Web App还是Client App。这样就统一了Web客户端APP和原生客户端APP。


    在服务器端Google拥有Golang。过去Google写web APP用Python、写android App用JAVA与C++、写服务器端代码用JAVA和C++,现在有了Golang。但显然,Google是想利用android的统治力来推动Dart的普及,想利用云计算的统治力来推动Golang的普及。端+云才构成完整技术闭环世界。


    这样来看,JAVA正在趋势退出Google。C++写服务器底层是必不可少也没有专有公司控制,但Dart和Golang在客户端/服务器端出现,Python和JAVA的退出就有隐线。


    Google在技术方面,似乎在CPU芯片、服务器、路由器交换器/路由协议/DNS、服务器操作系统、分布式文件系统、移动平板操作系统、数据库、浏览器、开发语言方面都希望自成一套体系。尤其Mysql数据库和JAVA都在Oracle手中,对于巨头来说这必须要有自己的护城河。


    过去Google收购Android,但一直无法控制android,Android团队似乎一直和google整体战略保持弱关系。随着人士斗争的结束,Android终于回到Google的掌控手心,开始和Chrome整合、和Chrome book整合、推出Android开发IDE。


    世界的另一端是Javascript。


    现在浏览器Web页面动作语言是Javascript,可跨浏览器,有很成熟的框架、大量的程序员和社区。


    Node.JS是借助V8引擎可以在服务器端运行。Node.js是Javascript语言。但Node.js并不是由V8负责人发明的。


    一个Google自己的世界,一个是开源世界,两个世界会并行存在谁也不会强过谁或谁衰退,只是另一种选择,你喜欢你就用。
    展开全文
  • 请不要犹豫,以下列数字为准:我的意图不是基于微基准将一种语言推广到另一种语言。 确实,您绝不应该仅基于其假定的性能来选择一种语言语言能力 我已经懒惰了很多年,只是采用了可以通过homebrew安装的语言,...
  • 为什么学习Dart? Google及全球的其他开发者,使用 Dart 开发了一系列高质量、 关键的 iOS、Android 和 web 应用。 Dart 非常适合移动和 web 应用的开发。 高效 Dart 语法清晰简洁,工具简单而强大。 输入检测可帮助...

    为什么学习Dart?

    Google及全球的其他开发者,使用 Dart 开发了一系列高质量、 关键的 iOS、Android 和 web 应用。

    Dart 非常适合移动和 web 应用的开发。

    高效

    Dart 语法清晰简洁,工具简单而强大。 输入检测可帮助您尽早识别细微错误。

    快速

    Dart 提供提前编译优化,以在移动设备和 web 上实现可预测的高性能和快速启动。

    可移植

    Dart 可以编译成 ARM 和 x86 代码,因此 Dart 移动应用程序可以在 iOS,Android 及 更高版本上实现本地运行。 对于 web 应用程序,Dart 可以转换为 JavaScript。

    易学

    Dart 是面向对象的编程语言,语法风格对于许多现有的开发人员来说都很熟悉。 如果您已经了解 C++,C# 或 Java ,那么使用 Dart 也就是分分钟的事情。

    响应式

    Dart 可以便捷的进行响应式编程。由于快速对象分配和垃圾收集器的实现, 对于管理短期对象(比如 UI 小部件), Dart 更加高效。 Dart 可以通过 Future 和 Stream 的特性和API实现异步编程。

    Dart " hello world "

    //Main程序入口
    void main(){
      //控制台打印
      print("Hello World!");
    }
    

    Dart 系列文章:https://www.cnblogs.com/jukaiit/category/1636484.html

    展开全文
  • 将ML模型转换为零依赖项的本地代码(Java,C,Python等)m2cgen m2cgen(模型2代码生成器)-是一种轻量级的库,它...pip install m2cgen支持的语言C C#Dart Go Haskell Java JavaScript PHP PowerShell Python R Rub
  • 算了,今天持续发烧,再来写写如何使用 Dart 语言的并发操作。说起并发操作,玩 Go 的同学该笑了,这就是我们的看家本领啊。玩 PHP 的同学继续看看,表示我们光看不说话。 代码演示之前,我们先假设一个场景。假设...
  • dart 小记

    2019-12-14 13:33:27
    最近在看flutter和dart,记录一下dart和javascript/java等常见语言不同一点特性。 dart 在面向对象和java类似,但是一些异步和动态性上和javascript类似。 字符串 使用三个引号表示多行字符串 String str2 = ''' ...
  • Dart语言学习理由

    2021-04-24 20:15:17
    随着跨平台移动 UI 框架 flutter 的走红,小众语言 ...它作为编程入门语言也非常合适(在我看来,入门 Dart 至少比入门 Java 更容易)。我曾为开发一个新项目而学习了 Dart,结果我深深爱上了这门语言,乃至想为它编写
  • 用二进制编程 操作整数的加,和逻辑否操作 发明子函数 发明栈 发明浮点数 1953年发明Fortran语言,那个时代都是手写在纸上。程序员写好程序,交给计算机硬件厂商去给硬件编码,程序员是不能碰到计算机的。有时候...
  • 每个人都必须使用具有面向对象范例的语言来进行对象构造。 但是,当您的对象有很多成员并且随时可能更改时,如何创建一个健壮的API保护您的使用者免受非被动更改的影响? 如何避免使用多个构造函数,这些构造函数...
  • dart dart2 区别翻译自: https://hackernoon.com/10-good-reasons-why-you-should-learn-dart-4b257708a332dart dart2 区别
  • void main() { LonLatAndXY latAndXY=new LonLatAndXY(); Tuple tuple=latAndXY.gps84ToXY(37.203267527777776,115.40381543333334,3); print(tuple.toString()); //我国划分为3或者6分带。...
  • 用Flutter开发Android App和iOS App需要使用Dart语言,所以本系列文章会深入介绍Dart语言的相关知识,后续还会推出Flutter App开发的系列文章,敬请期待...
  • Dart 2.12 现已发布

    2021-03-13 00:21:23
    作者 / Michael ThomsenDart 2.12 现已发布,其中包含 健全的空安全[1] 和 Dart FFI[2] 的稳定版。空安全是我们最新主打的一项生产力强化功能,意在帮助...
  • m2cgen (模型2代码生成器)-是一个轻量级的库,它提供了一种简便的方法,可以将经过训练的统计模型转换为本地代码(Python,C,JavaGo,JavaScript,Visual Basic,C#,PowerShell,R,PHP,Dart, Haskell,...
  • Dart 2.13 版现已发布

    2021-05-27 01:01:50
    作者 / Kevin Moore & Michael ThomsenDart 2.13 版现已发布,其中新增了类型别名功能,这是目前用户呼声第二高的语言功能。Dart 2.13 还...
  • GitJournal项目当前正在使用libgit2,但使用它却很麻烦-交叉编译,java ndk绑定+ ios绑定。 而且,它不能让我们轻松控制FS层。 我们最终要加密git repo。 因此,这是在Dart中重新实现Git的实验性起点。 目前,该...
  • flutter-Dart语言简介

    2019-03-14 15:35:52
    在之前我们已经介绍过Dart语言的相关特性,读者可以翻看一下,如果你熟悉Dart语法,可以跳过本节,如果你还不了解Dart,不用担心,按照笔者经验,如果你有过其他编程语言经验,尤其是Java和JavaScript的话,所以,...
  • Dart Bool类型和其他语言类似,比较简单 其特点有: 1.使用 bool 表示布尔类型 2.布尔值只有 true 和 false 3.布尔类型bool默认值是null bool isTrue = true; bool isFalse = false; bool defaultBool ; print...
  • 《持续发烧,聊聊Dart语言的并发处理,能挑战Go不?》 如果没有看过的同学,可以先看一下。 今天,我们再来谈谈 Dart 的另外一大优势,那就是静态编译。估计 php 和 python 直接认输, javago 冷眼旁观? 提前...
  • Dart 语言学习笔记一

    2018-12-11 10:26:14
    类似于JavaScript中的var,它可以接收任何类型的变量,但最大的不同是Dart中var变量一旦赋值,类型便会确定,则不能再改变其类型,如: ````dart var t; t=&quot;hi world&quot;; // 下面代码在dart...
  • 二、Dart

    2021-03-26 11:12:28
    一、dart SDK: https://dart.dev/get-dart 二、Dart关键字 关键字 abstract dynamic implements show as else import static assert enum in super async export interface switch await ...
  • Dart or golang? <p>I know, that java provide me hug ecosystem, but i don't like to learn java at all, just don't like java. <p>I would choose neo4j database, i am pretty sure, this suits for social...
  • dart 谷歌的野心 Google的Dart语言具有良好的null安全性 ,可帮助开发人员避免一类很难发现的错误。 “声音”为null的安全性意味着Dart 100%确保不可为空的变量不能为null。 Dart团队成员于6月10日表示,现在处于...
  • 深入理解 Dart 空安全

    千次阅读 2020-10-16 10:10:00
    编者按:本文为 Dart 空安全的经典详解,其详细且全面地展开说明了 Dart 处理空安全采用的原则、具体实现和技术细节,对于众多 Dart 开发者而言是不可错过的精华内容。无论你是否已...
  • 2. Flutter 之 Dart语言

    2019-12-08 11:51:21
    Flutter 开发框架采用的开发语言Dart Dart 是什么?...如同 Kotlin 和 Swift 的出现,分别是为了解决 Java 和 Objective-C 在编写应用程序的一些实际问题一样,Dart 的诞生正是要解决 JavaScri...
  • Dart语言语法特性简介(2)

    千次阅读 2017-11-27 10:44:36
    上一期主要介绍了dart和其他一些新语言比较类似的特性,这一期介绍一些dart里面独有,或者在其他语言里比较少看见的特性。1.内置对fluent api的支持,中文翻译过来应该是链式调用,或者流式调用 目前很多语言的库...
  • Dart 学习笔记

    2021-07-14 18:49:10
    虽然Dart是强类型语言,但变量类型是可选的因为Dart可以自动推断变量类型 Dart支持范型,List<int>表示一个整型的数据列表,List<dynamic>则是一个对象的列表,其中可以装任意对象 Dart支持顶层方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,797
精华内容 1,118
热门标签
关键字:

dartgojava

java 订阅