首页 >> 导购 >> Ballerina:面向数据程式设计

Ballerina:面向数据程式设计

2025-11-22 12:16:44

type Book record {string title;Author author;};

type Member record {string firstName;string lastName;int age;Book[] books;};

某种程度,与时序子类语义一样,在 Ballerina 中的,我们也可以用数据资料就是指使用量来始创数据资料。

Member kelly = {firstName: "Kelly",lastName: "Kapowski",age: 17,books: [{title: "The Volleyball Handbook",author: {firstName: "Bob",lastName: "Miller"}}]};

当然,与习惯的快照子类语义一样,如果我们遗漏了历史记录子类的某个URL,子类子系统则会让我们坚信。我们的编码很难通过载入,C#则会得知我们确实的状况。

Author yehonathan = {firstName: "Yehonathan"};ERROR [...] missing non-defaultable required record field 'lastName'

如果 VSCode 中的配备了 Ballerina 插件,就则会授予关于缺失URL的通告。

现在,你确实则会问自己,Ballerina 的子类子系统是快照的还是时序的。紧接著,让我们来看一看。

迅捷的 Ballerina 子类子系统

在一个大数据资料的程序来中的,用URL来缓冲数据资料是非常常见的。例如,也就是说我想给图书馆笔记的数据资料上升 fullName URL,这个URL坚称作笔记的原称。

在习惯的快照子类语义中的,我必须为在此之后缓冲的数据资料始创一个在此之后的子类,比如一个别名 EnrichedAuthor 的在此之后子类。但在 Ballerina 中的,这不是非常需要的,它的子类子系统强制你运用于中的括号坚称作法时序地附加URL,就跟时序子类语义一样。例如,在一个大的事例中的,我们将 fullName URL附加到 Author 历史记录中的:

Author yehonathan = {firstName: "Yehonathan",lastName: "Sharvit"};

yehonathan["fullName"] = "Yehonathan Sharvit";

这种语义功用让人沮丧大放异彩。从某种意义上却说,Ballerina 朴素地导入了两种不尽相同英文字出字母彼此之间的语义差异官能,让开发设计人员可以鱼属和熊掌兼得:

当我们运用于点号回访或修订历史记录URL时,Ballerina 为我们获取了与快照子类语义完全相同的安全官能。 当我们运用于中的括号来回访或修订历史记录URL时,Ballerina 为我们获取了时序子类语义的适应官能。

在某些意味着,我们想要严谨一些,不强制附加URL。这没疑问,因为 Ballerina 赞成堵塞历史记录。堵塞历史记录的语义与开放历史记录的语义完全相同,只是URL列表都有在两个|字符中的间。

type ClosedAuthor record {|string firstName;string lastName;|};

ClosedAuthor yehonathan = {firstName: "Yehonathan",lastName: "Sharvit"};

子类子系统不强制你向堵塞历史记录附加URL。

yehonathan["fullName"] = "Yehonathan Sharvit";ERROR [...] undefined field 'fullName' in 'ClosedAuthor'

Ballerina 还赞成运用于问号来坚称作可选URL。在一个大的历史记录中的,笔记的英文名字是可选的。

type AuthorWithOptionalFirstName record {string firstName?;string lastName;};

在回访历史记录的可选URL时,你必须管控好URL不存在的持续官能。在习惯的时序子类语义中的,由于毕竟快照子类健康检查器,开发设计人员很难以就忘了管控这种持续官能。1965 年,Tony Hoare 在三门别名 ALGOL 的脚本语义语义中的导入了空引用,后来,他指出这是 一个重要官能数十亿美元的偏差。

Ballerina 的子类子系统并未为你到时了一切。也就是说你就让执笔一个将笔记的英文名字转化成英文字出的变量。

function upperCaseFirstName(AuthorWithOptionalFirstName author) {author.firstName = author.firstName.toUpperAscii;}

这段编码很难通过载入:子类子系统 (和 VSCode 的 Ballerina 扩展插件) 则会警醒你很难保证可选URL的存在。

ERROR [...] undefined function 'toUpperAscii' in type 'string?'

那么,我们该如何修订我们的编码,以便正确地管控可选URL缺失的持续官能呢?很有用,就是在回访可选URL后,健康检查它应该存在。在 Ballerina 中的,URL的缺失运用于 来坚称作。

function upperCaseFirstName(AuthorWithOptionalFirstName author) {string? firstName = author.firstName;if (firstName is ) {return;}author.firstName = firstName.toUpperAscii;}

必须同样的是,这里不必须顺利进行子类转换。子类子系统有限精明,它坚信在健康检查变使用量 firstName 不是 之后,就可以保证它是一个URL。

我辨认出 Ballerina 的子类子系统还有一个非常有用的地方,即历史记录子类只必须通过URL结构来定义。这个让我来解释一下。

当我们在开发设计一个配置数据资料的程序来时,大部分编码都是由调拨数据资料和送回数据资料的变量分成。每个变量都对它调拨的数据资料文件格式难免允许。

在快照子类语义中的,这些允许坚称作为子类或类。通过查看变量签名就可以确实地坚信变量的数据资料文件格式。疑问是,这样则会在编码和数据资料彼此之间所致紧密的耦合。

让我举个事例。也就是说你想写出一个送回笔记原称的变量,你确实则会这样写出:

function fullName(Author author) returns string {return author.firstName + " " + author.lastName;}

这个变量的局限官能是它只能管控 Author 子类的历史记录。它不拒绝接受 Member 子类的历史记录,这让我沮丧实在太失望。毕竟,Member 历史记录也则会有 firstName 和 lastName URL。

必须同样的是,一些快照子类语义强制你通过始创数据资料以太网来绕开这个限制。

时序子类语义要迅捷得多。例如,在 Java 中的,你可以像这样实现变量:

function fullName(author) {return author.firstName + " " + author.lastName;}

变量的变量名是 author,但实际上,它可以拒绝接受任何不具 firstName 和 lastName URLURL的数据资料。疑问是,当你传授给它一个不都有这些URL(或其中的一个)的数据资料时,它将则会碰到运营时异常。此外,变量的意味著数据资料文件格式并没有在编码中的体现。因此,要坚信变量必须什么样的数据资料,我们要么依赖于文档 (它非常总是最在此之后的),要么必须研究一下变量的编码。

Ballerina 的子类子系统强制你在不牺牲适应官能的意味着而无须变量变量的文件格式。你可以始创一个在此之后的历史记录子类,并只提到正常调用变量所需的URL。

type Named record {string firstName;string lastName;};

function fullName(Named a) returns string {return a.firstName + " " + a.lastName;}

小贴士:你可以运用于匿名历史记录子类来而无须变量变量的文件格式。

function fullName(record {string firstName;string lastName;} a)returns string {return a.firstName + " " + a.lastName;}

你可以运用于任何都有非常需要URL的历史记录来调用变量,无论它是 Member 或 Author,还是任何其他不具变量所期望的URL的历史记录。

Member kelly = {firstName: "Kelly",lastName: "Kapowski",age: 17,books: [{title: "The Volleyball Handbook",author: {firstName: "Bob",lastName: "Miller",fullName: "Bob Miller"}}]};

fullName(kelly);// "Kelly Kapowski"

fullName(kelly.books[0].author);// "Bob Miller"

我觉得 Ballerina 管控子类的方式则可以用一个类比来却说明:子类就举例来说我们在程序来中的用来推论想象的主镜。但必须同样的是,我们来进行主镜碰到的只是想象的一个总体,它不是想象本身。就像谚语却说的:地图非常是版图。

例如,我们不用确实地却说 fullName 变量拒绝接受的一定是一个有英文名字的历史记录,而应该是却说,fullName 变量通过有英文名字的历史记录主镜来决定要调拨的数据资料。

让我们来看另一个事例。在 Ballerina 中的,不具完全相同URL值的两种不尽相同子类的历史记录被指出是相等的。

Author yehonathan = {firstName: "Yehonathan",lastName: "Sharvit"};AuthorWithBooks sharvit = {firstName: "Yehonathan",lastName: "Sharvit"};yehonathan == sharvit;// true

首先,这种行为让我沮丧讶异。两种不尽相同子类的历史记录为什么被指出是相等的?但当我想到主镜的类比时,我坚信了:

这两种子类是两种不尽相同的主镜,它们碰到的是同一个想象。在我们的程序来中的,最重要的是想象,而不是主镜。有时候,习惯的快照子类语义却是来得强调主镜,而不是想象。

到目前为止,我们并未碰到了 Ballerina 的子类子系统不仅不则会放任到我们,还让我们的开发设计工作流来得高效。但其实 Ballerina 在这个基础上来得进一步,获取了一种强大且便利的方式则,强制我们通过坚称作官能查询语义来配置数据资料。

强大的坚称作官能查询语义

作为一个变量式脚本语义行家,在配置数据资料时,我常用的命令都是一些值得注意变量,如 map、filter 和 reduce。Ballerina 赞成变量式脚本语义,但在 Ballerina 中的管控数据资料配置的类同方式则是运用于坚称作官能查询语义,我们可以用它非常流畅地坚称作企业语义。

也就是说我们有一个历史记录子集,我们想完好满足特定条件的历史记录,会用一个URL缓冲这些历史记录。例如,也就是说我们想完好中文翻译都有单词“Volleyball”的著作,会用笔记的原称来缓冲它们。

这是一个缓冲著作笔记历史记录的变量。

function enrichAuthor(Book book) returns Book {book.author["fullName"] = fullName(book.author);return book;}

我们可以用 map、filter 和一些匿名变量来缓冲著作。

function enrichBooks(Book[] books) returns Book[] {return books.filter(function(Book book) returns boolean {return book.title.includes("Volleyball");}).map(function(Book book) returns Book {return enrichAuthor(book);});}

但这样很乏味,声明这两个匿名变量的子类也实在太烦人。但如果运用于 Ballerina 的查询语义,编码就则会来得比较有用,来得难以读者。

function enrichBooks(Book[] books) returns Book[] {return from var book in bookswhere book.title.includes("Volleyball")select enrichAuthor(book);}

Ballerina 的查询语义将在我们的 Ballerina 系列短文中的参考介绍。

在暂时介绍 JSON 相关的功用早先,我们先为变量执笔一个形式化。在 Ballerina 中的,当历史记录不具完全相同的URL和值时,它们就被指出是相等的。因此,要比较变量送回的数据资料和我们期望的数据资料就很难以了。

Book bookWithVolleyball = {title: "The Volleyball Handbook",author: {firstName: "Bob",lastName: "Miller"}};Book bookWithoutVolleyball = {title: "Friendship Bread",author: {firstName: "Darien",lastName: "Gee"}};Book[] books = [bookWithVolleyball, bookWithoutVolleyball];Book[] expectedResult = [{title: "The Volleyball Handbook",author: {firstName: "Bob",lastName: "Miller",fullName: "Bob Miller"}}];enrichBooks(books) == expectedResult;// true

小贴士:Ballerina 工具箱一个开箱即用的形式化框架。

我们并未碰到了 Ballerina 为程序来内的数据资料坚称作和数据资料配置获取了适应官能和易用官能,紧接著我们来看看如何在 Ballerina 和其他程序来彼此之间反之亦然数据资料。

内置 JSON 赞成

JSON 确实是最为流行的数据资料反之亦然文件格式。个人信息子系统中的的程序来通常通过相互发送 JSON URL顺利进行收发。当程序来必须通过网络发送数据资料时,它将数据资料结构碱基化为 JSON URL。当程序来接寄出 JSON URL时,则会解析它,并将其转换为数据资料结构。

Ballerina 是为应用插件时代而设计的脚本语义语义,它赞成 JSON 碱基化和 JSON 解析。任何历史记录都可以碱基化成 JSON URL,如下所示:

AuthorWithBooks yehonathan = {firstName: "Yehonathan",lastName: "Sharvit",numOfBooks: 1};

yehonathan.toJsonString;// {"firstName":"Yehonathan", "lastName":"Sharvit", "numOfBooks":1}

反过来,一个 JSON URL可以被解析成一条历史记录。在这里,我们必须确保安全我们管控的 JSON URL是有效率的 JSON URL和符合意味著的数据资料文件格式。

function helloAuthor(string authorStr) returns error? {Author|error author = authorStr.fromJsonStringWithType;if (author is error) {return author;} else {io:println("Hello, ", author.firstName, "!");}}

小贴士:Ballerina 为我们获取了一个特殊的健康检查(check)结构,可以通过来得比较有用流畅的方式则执笔完全相同的语义。

function helloAuthor(string authorStr) returns error? {Author author = check authorStr.fromJsonStringWithType;io:println("Hello, ", author.firstName, "!");}

必须同样的是,Ballerina 对 JSON 的赞成不仅限于碱基化和解析。事实上,Ballerina 获取了一个 JSON 子类,让你可以像在时序语义中的那样配置数据资料。Ballerina 的文职 JSON 功用将在我们的 Ballerina 系列短文中的介绍。

我们并未探险了 Ballerina 获取的关于数据资料坚称作、数据资料配置和数据资料收发的战术上。我们将用一个一个大数据资料的小型程序来范例来却说明这些战术上,并以此来之前我们的探险。

范例:轻而易举自在地管控数据资料

也就是说我们正在构建一个由多个程序来分成的图书馆馆子系统,这些程序来可以反之亦然关于则社团、图书馆和笔记的数据资料。其中的一个程序来必须管控则社团数据资料,缓冲则社团原称URL,只完好中文翻译都有“Volleyball”的著作,并在每本书中的附加笔记的原称。

程序来运用于 JSON 顺利进行收发:它调拨 JSON 文件格式的则社团数据资料,并期望以 JSON 文件格式送回数据资料。

以下是这个程序来的编码。

首先,我们始创自订历史记录子类。

type Author record {string firstName;string lastName;};

type Book record {string title;Author author;};

type Member record {string firstName;string lastName;int age;Book[] books?; // books 是一个可选URL};

然后,用一个变量计算不具 firstName 和 lastName URLURL的历史记录的原称。我们运用于匿名历史记录来坚称作这个强制执行。

function fullName(record {string firstName;string lastName;} a)returns string {return a.firstName + " " + a.lastName;}

我们运用于 Ballerina 查询语义来过滤和缓冲著作个人信息:

只完好中文翻译都有“Volleyball”的著作; 用笔记的原称缓冲书本的个人信息。 function enrichAuthor(Author author) returns Author {author["fullName"] = fullName(author);return author;}

function enrichBooks(Book[] books) returns Book[] {return from var {author, title} in bookswhere title.includes("Volleyball") // 过滤中文翻译不都有 Volleyball 的著作let Author enrichedAuthor = enrichAuthor(author) // 缓冲笔记URLselect {author: enrichedAuthor, title: title}; // 选择一些URL

现在,我们来执笔企业语义:它是一个变量,通过以下方式则来缓冲则社团历史记录:

则社团的原称; 经过筛选和缓冲的著作。 function enrichMember(Member member) returns Member {member["fullName"] = fullName(member); // fullName 变量可以拒绝接受则社团和笔记作为变量Book[]? books = member.books; // books 是一个可选URLif (books is ) { // 显式管控URL不存在的持续官能return member;}// 子类子系统有限精明,它坚信这里的著作一定是一个变量member.books = enrichBooks(books);return member;}

最后,我们执笔程序来入口,它将则会暂时做以下这些工作:

将 JSON 解析为 Member 历史记录; 调用管控企业语义的变量来授予一个缓冲过的则社团历史记录; 将结果碱基化为 JSON。

必须同样的是,我们必须管控接寄出的 JSON URL确实无效的疑问。我们是这样管控的:

我们声明送回值可以是一个URL或一个偏差; 我们针对 fromJsonStringWithType 送回的内容调用 check。 如果寄出的 JSON URL是无效的,Ballerina 将操作者碰到一个偏差。 function entryPoint(string memberJSON) returns string|error {Member member = check memberJSON.fromJsonStringWithType;var enrichedMember = enrichMember(member);return enrichedMember.toJsonString;}

这就是管控语义本身的编码。你可以在 GitHub 上寻找完整的编码。

为了让它变为一个真正的应用程序来,我将运用于 Ballerina 获取的众多收发协议中的的一个,如 HTTP、GraphQL、Kafka、gRPC、WebSockets 等。

总 结

在执笔本文中的注意到的那些编码片段时,我有一种冲动,我重在此之后玩游戏了 IDE 在管控快照子类语义时带给我的那种愉快的冲动。我讶异地辨认出,为了这种玩游戏,这次我不必须在坚称作官能和适应官能上暂时这两项权衡。要坚信,自从我开始运用于时序子类语义以来,其适应官能让我沉迷到很难自拔。

Ballerina 毕竟在不变动数据资料的意味着来得在此之后数据资料的能力,我并未习惯了在变量式脚本语义中的这么暂时做了。我很难在 Ballerina 中的通过自订变量来达到这一目的,因为它必须赞成泛型子类。但我想要在不久的无论如何,这个功能将被附加到 Ballerina 中的。

我指出 Ballerina 是一种通用的脚本语义语义,它管控数据资料的方式则非常适合用来构建个人信息子系统。在我看来,这是因为 Ballerina 的主要重要官能是围绕数据资料坚称作、数据资料配置和数据资料收发。

它把数据资料视为一等外籍人士; 它迅捷的子类子系统获取了比习惯快照子类语义来得大的适应官能,并且不则会在安全官能和辅助工具总体暂时这两项权衡; 与时序子类语义相比,它迅捷的子类子系统获取了来得多的辅助工具和安全官能,并且不则会影响坚称作的速率和能力; 它为数据资料配置获取了 坚称作官能查询语义; 它内置了 JSON 赞成。

你可以回访 ballerina.io 了解到来得多关于 Ballerina 的个人信息。

笔记简介:

Yehonathan Sharvit 是《一个大数据资料脚本语义》一书的笔记。他从 2001 年开始用 C++、Java、Java、Ruby、Python、Clojure 和 Ballerina 等语义执笔编码。他目前在 CyCognito 工作,是作为 Clojure 布道五军。除了开发设计应用于大规模构建数据资料管道的插件库,他还帮助其他开发设计人员执笔朴素且易于维护的编码。

原意链接:

是 Rust 还好了,还是主流脚本语义本来就这么折磨人?

我用一个JavaScript Web 应用替换了原生 iOS 应用,竟早就辨认出

腾讯加薪大税制:升职不单独调薪;马斯克称作特斯拉需裁员10%,无限期全球招聘;中国联通成立第三批军团|Q电脑系统

成为变量式脚本语义设计者四年,我为什么却说它既“流氓”又“可爱”

点个在看少个 bug👇

江苏皮肤病医院哪家比较专业
常州男科专科医院哪家好
四川白癜风
成都看白癜风去哪家医院
汕头妇科医院哪好
食品安全
如何安胎
通心络胶囊
太极急支糖浆适用于哪种咳嗽
五一病例增加,感染新冠后为什么要第一时间吃抗病毒药物?医生的解答来了。

上一篇: SycoTec研磨中心主轴丨提升机床研磨效率0成本改造升级方案

下一篇: 鹅厂领域专家出品:从 0 到1 开发 Go 实战项目 | 极客时间

相关阅读
闹笑话!女超比赛没担架,队医抱着红牌,人民体育痛批保障在哪里

北京时间5月8日,确信很多埃弗顿都看到了一个有趣的球类新闻,万众瞩目的女超足协杯刚刚世纪之交的进行时,其之前镇江无锡足足协杯赛对阵宁夏西安赛跑的半决赛早就打剩,两支足协杯0比0战平,有趣的是半决

2025-11-22 00:16:44
全新广州队亮相热身赛,国足未来之星出任队长,惊喜揭幕战未来可期

从新球队的北京国安热身赛何时开赛虽然现阶段还没一个最终的确知,但是现阶段各支联赛都仍然相继开始了对于从新球队的备战,而随着日前从新球队北京国安转就会售票处的在此之前停止,各支联赛从新球队的阵容也

2025-11-22 00:16:44
曼联0-4布莱顿:全队如同梦游,如此状态,换帅也难回击?

不能此时此刻,不能反击,利物浦甚至不能困兽之斗,一场0-4的惨败便,“传闻之前”方才不必为要强的争取欧冠参赛权的期望而努气了。在半决赛告一段落便,有赛前把责难的感觉给了C罗,毕竟这位爵爷亲自

2025-11-22 00:16:44
马布里中文网微博晒照:母亲节快乐~

孙悦专文网易晒照:双亲节孤独~ἳ8ἳ8ἳ8 现场直播吧5月8日讯 今日,孙悦专文网易晒照,惠孙悦双亲及女儿节日孤独。 两张特写分别为孙悦与父母的合照以及他与妻儿的

2025-11-22 00:16:44
大幅度降薪签约先于,博格巴害苦了自己,也耽误了曼联

根据荷兰独立国家记者Jacque Talbot的最新独家报道,尤文为博格巴开出薪金22万欧+奖金合同,安特卫普曼城仍在争夺他。 博格巴是一名优秀的国脚,在足球运动课题,他的天赋毋庸

2025-11-22 00:16:44