关于function:Function源码解析与实践

作者:陈昌浩1 导读if…else…在代码中常常应用,据说能够通过Java 8的Function接口来毁灭if…else…!Function接口是什么?如果通过Function接口接口毁灭if…else…呢?让咱们一起来摸索一下吧。 2 Function接口Function接口就是一个有且仅有一个形象办法,然而能够有多个非形象办法的接口,Function接口能够被隐式转换为 lambda 表达式。能够通过FunctionalInterface注解来校验Function接口的正确性。Java 8容许在接口中退出具体方法。接口中的具体方法有两种,default办法和static办法。 @FunctionalInterfaceinterface TestFunctionService{ void addHttp(String url);}那么就能够应用Lambda表达式来示意该接口的一个实现。 TestFunctionService testFunctionService = url -> System.out.println("http:" + url);2.1 FunctionalInterface2.1.1 源码@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface FunctionalInterface {}2.1.2 阐明 上图是FunctionalInterface的注解阐明。通过下面的注解阐明,能够晓得FunctionalInterface是一个注解,用来阐明一个接口是函数式接口。 函数式接口只有一个形象办法。 能够有默认办法,因为默认办法有一个实现,所以不是形象的。函数接口的实例能够用lambda表达式、办法援用或构造函数援用创立。 FunctionalInterface会校验接口是否满足函数式接口: 类型必须是接口类型,不能是正文类型、枚举或类。只能有一个形象办法。能够有多个默认办法和静态方法。能够显示笼罩java.lang.Object中的形象办法。编译器会将满足函数式接口定义的任何接口视为函数式接口,而不论该接口申明中是否应用FunctionalInterface注解。 3 Function接口次要分类Function接口次要分类: Function:Function函数的表现形式为接管一个参数,并返回一个值。Supplier:Supplier的表现形式为不承受参数、只返回数据。Consumer:Consumer接管一个参数,没有返回值。Runnable:Runnable的表现形式为即没有参数也没有返回值。3.1 FunctionFunction函数的表现形式为接管一个参数,并返回一个值。 3.1.1 源码@FunctionalInterfacepublic interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T, T> identity() { return t -> t; }}3.1.2 办法阐明apply:形象办法。将此函数利用于给定的参数。参数t通过具体的实现返回R。compose:default办法。返回一个复合函数,首先执行fefore函数利用于输出,而后将该函数利用于后果。如果任意一个函数的求值引发异样,则将其传递给组合函数的调用者。andThen:default办法。返回一个复合函数,该复合函数首先对其利用此函数它的输出,而后对后果利用after函数。如果任意一个函数的求值引发异样,则将其传递给组合函数的调用者。identity:static办法。返回一个始终返回其输出参数的函数。3.1.3 办法举例1)apply ...

November 29, 2022 · 3 min · jiezi

浅谈Kotlin中的函数

本文首发于 vivo互联网技术 微信公众号  链接:https://mp.weixin.qq.com/s/UV23Uw_969oVhiOdo4ZKAw 作者:连凌能Kotlin,已经被Android官方宣布 kotlin first 的存在,去翻 Android 官方文档的时候,发现提供的示例代码已经变成了 Kotlin。Kotlin的务实作风,提供了很多特性帮助开发者减少冗余代码的编写,可以提高效率,也能减少异常。 本文简单谈下Kotlin中的函数,包括表达式函数体,命名参数,默认参数,顶层函数,扩展函数,局部函数,Lambda表达式,成员引用,with/apply函数等。从例子入手,从一般写法到使用特性进行简化,再到原理解析。 1.表达式函数体通过下面这个简单的例子看下函数声明相关的概念,函数声明的关键字是fun,嗯,比JS的function还简单。 Kotlin中参数类型是放在变量:后面,函数返回类型也是。 fun max(a: Int, b: Int) : Int { if (a > b) { return a } else { return b }}当然, Kotlin是有类型推导功能,如果可以根据函数表达式推导出类型,也可以不写返回类型。 但是上面的还是有点繁琐,还能再简单,在 Kotlin中if是表达式,也就是有返回值的,因此可以直接return,另外判断式中只有一行一句也可以省略掉大括号: fun max(a: Int, b: Int) { return if (a > b) a else b}还能在简单点吗?可以,if是表达式,那么就可以通过表达式函数体返回: fun max(a: Int, b: Int) = if(a > b) a else b最终只需要一行代码。 Example 再看下面这个例子,后面会基于这个例子进行修改。这个函数把集合以某种格式输出,而不是默认的toString()。 <T>是泛型,在这里形参集合中的元素都是T类型。返回String类型。fun <T> joinToString( ...

November 4, 2019 · 6 min · jiezi

开发函数计算的正确姿势-Fun-validate-语法校验排错指南

1. 前言首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息 参考。Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档 参考。 template.yml: template.yml 用于定义 serverless 应用的模型。无论是使用 fun local 还是 fun deploy 等功能,都是通过解析 tempalte.yml 的内容,构建出用户定义的云资源模型,进而实现本地云资源的运行调试以及发布等功能。template.yml 支持的规范文档可以参考。 template.yml 所描述的 Serverless 模型,是 Fun 所有功能的基石。template.yml 的正确性对后续能够顺利使用 Fun 的各项功能无疑是非常关键的。为了帮助用户更快速的修正 template.yml 中错误的描述,我们在 Fun 2.14.0 优化了语法校验的错误信息,可以达到更精准定位报错并修复的目的。 下面我们就通过一个示例,学习如何根据报错信息纠正 template.yml 中的错误语法描述。 备注:请确保 Fun 工具版本在 2.14.0+ 2. 错误的 template.yml 示例ROSTemplateFormatVersion: '2015-09-01'Transform: 'Aliyun::Serverless-2018-04-03'Resources: local-http-demo: Type: 'Aliyun::Serverless::InvalidService' Properties: Description: 'local invoke demo' nodejs8: Type: 'Aliyun::Serverless::InvalidFunction' Properties: Handler: index.handler CodeUri: nodejs8/ Description: 'http trigger demo with nodejs8!' Events: http-test: Type: HTTP Properties: AuthType: ANONYMOUS Method: ['GET', 'POST', 'PUT']在上面的示例中,我们原意是想要描述一个叫做 local-http-demo 的服务,并在服务下定义了一个名为 nodejs8 的函数,同时为该函数配置一个匿名的 HTTP 触发器,支持 GET、POST、PUT 的 HTTP 请求。 ...

May 22, 2019 · 3 min · jiezi

胡说-JavaScript函数类型

回到了自己的家乡,期待中有感觉到了很多的陌生,一个有“故事”的环境中,你我是否“孤独”!函数的类型在我看来function共有三种类型,作为对象使用,处理业务以及穿件object的实例对象。跟这三种用法相对应的有三种子类型,分别是对象的属性、变量(包括参数)和创建出来的object类型实例对象的属性。这三种子类是相互独立的,而且也很容易区分。但是,我们刚刚接触的时候很容易混淆。1.function 作为对象来使用这种情况下,function对象的子类型就是对象自己的属性,这时通过操作符“.”(或者方括号操作符)使用,示例如下:function book(){}book.price=999;book[“getPrice”]=function(){ return this.price;}console.log(book.getPrice()); //输出结果:999我很少碰到function来作为object类型的对象来使用。2.funciton 用于处理业务这种情况下,function的子类型就是自己定义的局部变量(包括参数),这时的变量实在方法被调用时通过变量作用域链来管理的。关于变量我之前的文档中有涉及到,这里就不过多的说明了。3.function 用于创建对象这种情况下,对应的子类型是使用function创建实例对象的属性(很常用),主要包括在function中通过this添加属性,以及创建完成之后实例对象自己添加的属性。另外,还可以调用function的prototype属性对象所包含的属性,示例如下:function Car(color,displacement){ this.color = color; this.displacement = displacement;}Car.prototype.logMessage = function(){ console.log(this.color+","+this.displacement); };var car = new Car(“yellow”,“2.4T”);//看看是不是类似构造函数?哈哈这个例子中创建的car对象就包含有color和displacement两个属性,而且还可以调用Car.prototype的logMessage方法。当然,创建完之后还可以使用点操作符给创建的car对象添加或者修改属性,也可以使用delete删除其中的属性,示例如下:function Car(color,displacement){ this.color = color; this.displacement = displacement;}//所有创建出来的car都有该方法Car.prototype.logMessage = function(){ console.log(this.color+","+this.displacement); };var car = new Car(“yellow”,“2.4T”);//看看是不是类似构造函数?哈哈//给car对象添加属性car.logColor = function(){ console.log(this.color); };//完成调用测试car.logColor();//输出结果: yellowcar.color = “red”;car.logColor();//输出结果:reddelete car.color;//删除属性car.logColor();//输出结果:undefined代码分析:在创建完car对象之后,又给它添加了logColor的方法,可以打印car的color属性。添加完logColor方法后直接调用就可以打印出car原来的color属性值(yellow)。然后,将其修改为red,在打印出了red。最后,使用delete删除car的color的属性,这时在调用logColor方法会打印出undefined其实跟我的注释说明一致!!!三种子类型的关系function的三种子类型是相互独立的,他们只能在自己所对应的环境中使用而不能相互调用,示例如下:function log(msg){//第二种业务处理 console.log(msg);}function Bird(){ var name = “kitty”; this.type = “pigeon”; this.getName = function(){ return this.name;//创建的对象没有name属性 }}Bird.color = “white”;//第一种object类型的对象Bird.getType = function(){//第一种object类型的对象 return this.type;};Bird.prototype.getColor = function(){//第三种创建对象 return this.color;}var bird = new Bird();log(bird.getColor());// undefinedlog(bird.getName()); // undefinedlog(bird.getType()); // undefinedBird 作为对象时包含 color 和 getType 两个属性,作为处理业务的函数是包含一个名为name的局部变量,创建的实例对象bird具有type和getName两个属性,而且还可以调用Bird.prototype的getColor属性,getColor也可以看作bird的属性。用 法子 类 型对象(Bird)color 、getType处理业务(Bird方法)name创建实例对象(bird)type、getName、(getColor)每种用法中所定义的方法只能调用相对应所对应的属性,而不能交叉调用,从对应关系中可以看出,getName、getColor和getType三个方法中无法获取到值,大家再仔细分析一下!另外,getName和getColor是bird的属性方法,getType是Bird的属性方法,如果用Bird对象调用getName或getColor方法或者使用bird对象调用getType方法都会抛出找不到的错误。三种子类型不可以相互进行调用之外,还有一种情况也非常重要:那就是对象的属性并没有继承的关系。function obj(){}obj.v=1;obj.func = { logV : function(){ console.log(this.v); }}obj.func.logV();代码分析:这个例子中的obj是作为对象使用的,obj是有一个属性v和一个对象属性func,func对象中又有一个logV方法,logV方法用于打印对象的v属性。这里需要特别注意:logV方法打印的是func对象的v属性,但是func对象中并没有v属性,所以最后结果是undefined。这个例子中,虽然obj对象中包含v属性,但是由于属性不可以继承,所以obj的func属性对象中的方法不可以使用obj中的属性v.请大家一定要记住,并且不要和prototype的继承以及变量作用域链相混淆关联三种子类型三种子类型本来是相互独立、各有各的使用环境的,但是,有一些情况下需要操作不属于自己所对应环境的子类型,这时就需要使用一些技巧来实现了。约定如下function 作为对象使用时记作 O(Object)作为函数使用时记作 F(Function)创建出来的对象实例记作 I(Instance)op(object property)v(variable)ip(instance property) opvipO直接调用在函数中关联到O的属性不可调用F使用O调用直接调用不可调用I使用O调用在函数中关联到I的属性直接调用纵向表头表示function的不同用法横向表头表示三种类型,表格的主体表示在function相应用法中调用各种子类的方法。因为function创建的实例对象在创建之前还不存在,所以function作为方法(F)和作为对象(O)使用时无法调用function创建的实例对象的属性(ip)。调用参数可以在函数中将变量关联到相应的属性,调用function作为对象(O)时的属性可以直接使用 function 对象来调用function log(msg){ console.log(msg);}function Bird(){ //私有属性 var name = “kitty”; var type = “pigeon”; //将局部变量name关联到新创建的对象的getName,setName属性方法 //闭包可以使用局部变量 //公有属性 this.getName = function(){ return name; } this.setName = function(n){ name = n; } //将局部变量type关联到Bird对象getType属性方法 //静态属性 Bird.type = function(){ return type; } //在业务处理中调用Bird对象的color属性 log(Bird.color);//输出结果: white,F调用op }Bird.color = “white”;// 代表 O//在创建出的实例对象中调用Bird对象的color属性Bird.prototype.getColor = function(){//I return Bird.color;//OP}var bird = new Bird(); // 创建实例 Ilog(bird.getColor()); // 输出结果:white , I 调用 oplog(bird.getName());// 输出结果:kitty , I 调用 v 局部变量log(Bird.getType());// 输出结果:pigeon , O 调用 v 局部变量bird.setName(“petter”); // I 调用 vlog(bird.getName());// 输出结果:petter , I 调用 v 局部变量好好分析上述的代码,非常经典的,了解三种子类型的不同环境用法中交叉调用的方法附录:“公有属性” “私有属性” 和 “静态属性”上面的示例中我们涉及到了公有属性、私有属性和静态属性的说明,由于JS并不是基本类而是基于对象的语言,因此JS本身并没有这些概念。公有属性:一般指使用function对象创建出object实例对象所拥有的属性。私有属性:一般指function的内部变量静态属性:一般指function对象自己的属性 ...

January 26, 2019 · 1 min · jiezi