dart语言和java语言_Java中您可能会错过的14种打字稿和Dart语言功能

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语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值