python kotlin_Java和Python中类似Kotlin的生成器,续:附加参数

python kotlin

介绍

在今天的文章中,我们将继续上周的文章,内容涉及使用Java和Python创建类似Kotlin的构建器,并扩展了构建器API以采用一些可选参数以提高灵活性。 我们继续我们HTML示例,尝试添加标记属性,例如class,id和style。

Kotlin和Python

Kotlin设置使用这些参数的方式与我在Python中的使用方式完全相同:默认参数和命名参数。 使用Kotlin看起来像这样:

html {body {p(klass="myClass", id="theParagraph") {+ "the paragraph text"}}
}

请注意,使用“杯子”而不是“类”。 关键字和标识符的经典冲突。 您可以根据需要使用“ cls”,“ clazz”或其他任何东西。 我建议不要使用类对象语言中通常使用的任何东西,因为这是完全不同的类。

与上周的p标签相比,这是一个很大的升级(只是p = "text" ),将其从属性更改为成熟的方法。 但是大多数其他示例不需要太多工作。 这是更新的Kotlin代码:

class Body {...fun p(class: String="", id: String="", style: Style=Style.blank, paragraphBuilder: Paragraph.() -> Unit) {val p = Paragraph(class, id, style)paragraphs.add(p)p.paragraphBuilder()}...
}class Paragraph(val class: String, val id: String, val style: Style) {var text: String = ""operator fun plus(other: String) {text += other}
}

更新后的Python代码(仍使用第一个版本)如下所示:

class Body:def __init__(self):self.paragraphs = ...def p(self, klass='', id='', style=None):par = Paragraph(klass, id, style)self.paragraphs.append(par)return parclass Paragraph:def __init__(self, klass, id, style):self.klass = klassself.id = idself.style = styleself.text = ''def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):return Falsedef __iadd__(self, text):self.text += text

__iadd__()是就地加法运算符,允许我们说p += 'text' 。 在Kotlin中,我们使用+而不是+=因为我们不必引用段落对象,因此从+=开头看起来是错误的,而我们需要在Python代码中引用p ,因此+=看起来更自然,这样,我们就可以将调用代码更改为以下形式:

html = Html()
with html as html:with html.body() as body:with body.p(class='myClass', id='theParagraph') as p:p += 'the paragraph text'

Kotlin和Python都采用Style对象,而不是像其他字符串一样仅接受另一个字符串。 实际上,我建议也对class和id做同样的事情,因为从那时起,我们将class和id对象及其CSS设置传递给CSS生成器。 我只是为了举例而没有在这里做。 我不让Style保留字符串,因为最好使用某种CSS样式生成器来提供更好的清晰度和正确性。

Java

Kotlin和Python都使过渡非常简单。 不幸的是,Java没有设置必需的功能来进行如此简单的更改。 您必须依靠古老的流利的API技巧来使您理解它。

重载嘉豪!

首先想到的是尽可能多地进行带有大量重载的转换。 您可以为class和id字段创建快速,方便的字符串包装器,因为它们都只是字符串,因此很难区分两者:

class Class {public final String text;public Class(String text) {this.text = text;}
}class ID {public final String text;public ID(String text) {this.text = text;}
}

这使得所有重载看起来像这样:

class Body {...public void p(Consumer<Paragraph> paragraphBuilder) {...}public void p(Class klass, Consumer...) {...}public void p(ID id, Consumer...) {...}public void p(Style style, Consumer...) {...}public void p(Class klass, ID id, Consumer...) {...}// and so on... 3 more times...
}

这变得非常乏味,以至于我什至没有写完每一行,更不用说开始所有行了。 而且这仅考虑了类,id和样式。 还有更多。 走这条路是不好的。 因此,我什至不会显示结果代码的样子。 另外,对于其余的想法,我不会费心地展示API的实现,希望它是不言而喻的。 如果您真的对如何实现其中一种API感到好奇,请告诉我。

内部设定

设置这些属性的另一种方法是在构建器中进行设置。 提供用于设置这些值的“ Paragraph方法。 在body标签内看起来像这样:

html.body(body -> {body.p(p -> { p.klass = "myClass"; p.id = "theParagraph";p.addText("the paragraph text");});
});

这并不可怕(特别是在第一行上有那些设置程序行;将它们放在后续行上会混淆其目的),并且这可能是最简单的,但是错误代码的可能性会很高:

html.body(body -> {body.p(p -> {p.klass = "myClass";p.addText("the paragraph text");p.id = "theParagraph";});
});

让我们看看其他选项。

属性对象

仅使用p()两个重载(一个仅接受构建器函数的重载,以及一个既接受构建器函数又包含Attributes对象的重载),我们可以制作一个非常干净的API,看起来像这样:

html.body(body -> {body.p(Attributes.klass("myClass").id("theParagraph"), p -> {p.addText("the paragraph text");});
});

就个人而言,这是我的最爱。 它需要更多的类和更多的实际复杂性,但是我觉得它是最可扩展的。 最大的不便是不同HTML标签具有不同的属性集。 可能应该有一个公共的Attributes构建器类,再加上一个特定于标记的类,从而使重载次数最多达到4(没有属性,只有基本的属性,只有特定于标记的属性,以及这两种类型)。 四个重载是可以容忍的,但可能不应该。 如果看起来太多,最好坚持最后一种策略。

不过,为了完整起见,我还有一个,它实际上可能对其他不模仿HTML或XML的API更好地工作。

通话后大楼

最后一个想法是让Body.p()返回Paragraph (最好是构建器的第二阶段,因为这些方法可以在构建器lambda中使用,否则可以调用它们),如下所示:

html.body(body -> {body.p(p -> {p.addText("the paragraph text");}).klass("myClass").id("theParagraph");
});

这实际上将Attributes类移到末尾,作为“ Paragraph构建器的第二阶段。

奥托罗

那是我能给你的最好的。 如果您有兴趣使用Java之类的语言来构建流畅的API,则应查阅jOOQ的文章,了解它们的用法 。 这是一种完全不考虑lambda的不同方式,这很好。 无论如何,下周我将发表一系列简短的书评文章时,我将与你们交谈。

翻译自: https://www.javacodegeeks.com/2016/01/kotlin-like-builders-java-python-continued-additional-parameters.html

python kotlin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336604.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

按钮自动居中布局_CSS布局技巧

css实现左右布局和居中布局显示是前端进行页面设计的基础&#xff0c;也是全面了解并学习css一个很好的切入点&#xff0c;因为其中会涉及到对许多css基础点的认知。实现css入门&#xff0c;理解左右布局的实现方式是必经之路&#xff0c;同时也能使我们在项目中涉及前端编码的…

jooq_jOOQ星期二:拉斐尔·温特豪德(Rafael Winterhalter)正在与字节好友合作字节码...

jooq欢迎来到jOOQ Tuesdays系列。 在本系列文章中&#xff0c;我们每隔一个月的第三个星期二发布一篇文章&#xff0c;从jOOQ的角度采访我们发现该行业令人兴奋的人。 这包括从事SQL&#xff0c;Java&#xff0c;开放源代码以及各种其他相关主题的人员。 我们很高兴在第七版中…

多方法接口回调_啊?Java反射遇到接口

本文适合有点Java反射基础的同学&#xff0c;在Java反射调用方法时遇到接口参数是一件很蛋疼的事情。在反射调用方法时需要传参数&#xff0c;像传递基本数据类型进去用就完事&#xff0c;传个对象进去怎么整都没关系&#xff0c;因为你在外部有对象的引用&#xff0c;但 如果需…

0与1世界的初级编程篇之C语言

C语言是一门面向过程的计算机编程语言&#xff0c;与C、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速&#xff0c;工作量小…

swarm部署集群_WildFly Swarm –将Java EE应用程序部署为独立的Jar

swarm部署集群WildFly Swarm提供了一个简单的解决方案&#xff0c;用于将Java EE应用程序部署为独立的Jar文件。 这使得部署应用程序非常容易&#xff0c;尤其是REST或Web服务。 Swarm在这方面与Spring Boot非常相似&#xff0c;因为它可以快速开发Web&#xff08;.War&#xf…

QT 手动创建信号函数 与 槽函数

自定义信号槽必须要有Q_OBJCT 自己通过关键字signals创建信号函数,只声明信号函数即可&#xff0c;系统会自动定义它。 利用 public slots: 声明一个槽函数&#xff0c;槽函数不会自动生成&#xff0c;并且去定义它。

九九乘法表代码口述_利用随机函数实现座次表的随机排座

昨天听完讲座&#xff0c;晚上忍不住写了份学后感&#xff0c;今天有老师在文章下留言问如何实现随机排座&#xff0c;上午在快速理赔中心处理交通事故&#xff0c;处理完后将车开去4S店维修&#xff0c;回来后给娃做完中饭就开始写代码实现这个功能&#xff0c;因为有C功底&am…

jep使用_JEP 277“增强弃用”非常好。 但这是一个更好的选择

jep使用维护API很难。 我们正在维护非常复杂的jOOQ API。 但是就语义版本而言&#xff0c;我们遵循相对宽松的规则 。 当您阅读Brian Goetz和其他人关于在JDK中保持向后兼容性的评论时&#xff0c;我只能对他们的工作表示敬意。 显然&#xff0c;我们都希望最终移除Vector &a…

python 港股交易数据_GitHub - 116pythonZS/futuquant: 富途量化平台 API

FutuQuant - 富途量化投资平台 (Futu Quant Trading API)简介​FutuQuant开源项目可以满足使用富途牛牛软件进行量化投资的需求, 提供包括Python接口、Json接口的行情及交易的API。安装pip install futuquant注: 本API同时兼容Python2和Python3, 推荐安装anaconda环境&#xff…

LeetCode 16.01 交换两数

原题链接 交换 a,b两个数&#xff0c;不开辟额外控件 解析&#xff1a; 设a甲 b乙 aa^b; 转换 a甲^乙 b乙 ba^b; 转换 b甲^乙^乙 因为 乙^乙0 甲^0甲 &#xff0c;所以b甲 aa^b; 转换 a甲^乙^甲 同上所述&#xff0c;所以 a乙 至此…

古巴比伦乘法_古巴平台中的通用过滤器–类固醇上的excel过滤器

古巴比伦乘法正如我上次承诺的那样&#xff0c;我计划浏览该平台的某些功能&#xff0c;这些功能我认为非常有价值。 所以我将在这里做一些系列。 从明显的用户界面&#xff0c;过滤&#xff0c;安全性到一些高级功能&#xff08;如Web Portal&#xff0c;可扩展性&#xff0c;…

excel运行没反应_Excel数据很少文件却很大,问题出在哪里呢?两种方法轻松解决...

经常和Excel打交道的小伙伴可能会有这样的困惑&#xff0c;一个Excel工作簿中的数据明明很少&#xff0c;文件所占的空间却很大。打开这种Excel工作簿后&#xff0c;电脑CPU占用率瞬间飙升&#xff0c;甚至遇见工作簿没有响应的情况出现。遇见这样的工作簿让人窝火&#xff0c;…

约瑟夫环问题题解

按照1-8顺寻存储&#xff0c;起始位置为3&#xff0c;数到4的人出列。 #include<iostream> using namespace std; typedef struct node {int num;struct node* next; }Node; int main() {int n 8, k 3, m 4;Node*h (Node*)malloc(sizeof(Node));h->num 1;h->n…

java lambda::_基准测试:Java 8 Lambda和流如何使您的代码慢5倍

java lambda::与长期的实现相比&#xff0c;Java 8 lambda和流的性能如何&#xff1f; Lambda表达式和流在Java 8中受到了热烈的欢迎。这些是迄今为止很激动人心的功能&#xff0c;很长一段时间以来&#xff0c;它们就已经应用到Java中了。 新的语言功能使我们可以在代码中采用…

如何在java中实现小数点自增_java编个计算器怎么在加入小数点

展开全部我做的可以运行&#xff0c;你看看吧&#xff01;import java.awt.*;import java.awt.event.*;import java.lang.*;import javax.swing.*;public class Counter extends Frame{//声明三个面板的布局GridLayout gl1,gl2,gl3;Panel p0,p1,p2,p3;JTextField tf1;TextField…

数组中一个属出现奇数次,其他数都出现偶数次.寻找出这个出现奇数次的数

#include<iostream> #include<vector> using namespace std; int singleNumber(vector<int>& nums) {int eo 0;for (auto b : nums)eo ^ b;return eo; }

在Java中使用FileChannel和ByteBuffer对文件进行读写

过去&#xff0c;我讨论过RandomAccessFile以及如何将其用于在Java中进行更快的IO&#xff0c;在本Java NIO教程中&#xff0c;我们将了解如何通过使用FileChannel和ByteBuffer来使用读/写数据。 Channel提供了一种从文件读取数据的替代方法&#xff0c;它提供了比InputStream…

tp5防止sql注入mysql_PHP+Mysql防止SQL注入的方法(life)

这篇文章介绍的内容是关于PHPMysql防止SQL注入的方法&#xff0c;有着一定的参考价值&#xff0c;现在分享给大家&#xff0c;有需要的朋友可以参考一下我的官方群点击此处。方法一&#xff1a;mysql_real_escape_string -- 转义 SQL 语句中使用的字符串中的特殊字符&#xff0…

neo4j 关系属性_Neo4j:特定关系与一般关系+属性

neo4j 关系属性为了在Neo4j查询中获得最佳的遍历速度&#xff0c;我们应该使关系类型尽可能具体 。 让我们看一下几周前我在Skillsmatter上发表的“ 建模建议引擎建模 ”演讲中的一个例子。 我需要决定如何为成员和事件之间的“ RSVP”关系建模。 一个人可以对某个事件表示“…

(Tree)二叉树基本操作

//二叉树操作#include<iostream> #include<algorithm> using namespace std;//准备数据#define MANLEN 20 typedef char DATA; typedef struct CBT {DATA data;struct CBT*left;struct CBT*right; }CBTT;//初始二叉树,设置一个根节点CBTT* InitTree() {CBTT* node;…