为了账号安全,请及时绑定邮箱和手机立即绑定
2.2 函数调用

当函数定义好了,在需要使用函数的地方,调用其函数名称即可,注意函数调用需要在函数定义之后。2.2.1 无参数调用当函数没有参数的时候,调用非常简单,直接写函数名称即可,调用函数就是在特定地方执行函数体内的操作。// 定义函数function fnname() { statements return value}// 调用函数fname2.2.2 传递参数调用语法我们之前在变量一章节介绍了 Shell 脚本的参数,知道了参数的重要性质及其各种类特征,与 Shell 脚本传递参数一样,函数也可以传递参数,例如:// 定义函数function fnname() { statements return value}// 调用函数fname param1 param2 param3如上所示,在调用函数 fname 的时候,我们传递了三个参数,参数之间利用空格分割,和 Shell 脚本传递参数一样,但需要注意 Shell 脚本中,函数在定义时候不能指定参数,在调用的时候传递参数即可,并且在调用函数时传递什么参数函数就接受什么参数。

1.2 调用函数

使用 函数名() 的方式即可调用一个函数以下是一个最简单的函数:function say() { console.log('hello');}say(); // 输出:"hello"调用这个函数就会在控制台输出 hello 字符串。这个函数没有返回值,默认会返回一个 undefined。

3. 函数调用过程

在所有的编程语言中,函数的调用都是这样的过程:将当前调用函数的下一个指令地址压入堆栈,并保存现场环境;调到调用函数地址去执行;调用函数执行完成后,调用 ret 指令弹出下一步执行的地址,返回到原来的函数中接着执行下一条语句。示意图如下: 函数调用过程自己调用也是一样的过程,并不会说自己调用自己递归就会在函数内部执行,同样是在另一个地址有一份相同的函数代码拷贝,也就是将上图中的函数 B() 换成函数 A(),这幅图同样正确。递归调用的示意图如下:递归调用示意图

2.2 简化函数调用

现在需要多次调用 add_student 对一批学生进行处理,可以使用如下代码:41在第 6 行到第 10 行,新增 5 个学生 tom、jerry、mike、john、jobs大部分学生来自于相同的城市,极个别学生来自于外地城市使用默认参数,可以简化函数的调用,尤其是在函数需要被频繁调用的情况下。因为大部分学生来自于 nanjing,可以为参数 city 设定一个默认值 nanjing,如下所示:42在第 6 行到第 10 行,新增 4 个学生 tom、jerry、mike、john,这 4 个学生来自于相同的城市 ‘nanjing’,调用函数 add_student 时不需要的传递参数 ‘nanjing’在第 10 行,新增 1 个学生 jobs,该学生来自于 beijing,调用函数 add_student 时需要的传递参数 ‘beijing’

TensorFlow 中的回调函数

回调函数是 TensorFlow 训练之中非常重要的一部分,我们在之前的学习之中或多或少地用到了回调函数。比如在之前的过拟合一节之中,我们就曾经用到了早停回调。那么这节课我们就来学习以下 TensorFlow 之中的回调函数。

1. 什么是回调函数

简单来说,回调函数就是在训练到一定阶段的时候而执行的函数,我们最常采用的策略是每个Epoch结束之后执行一次回调函数。回调函数的绝大多数 API 集中在 tf.keras.callbacks 之中,也就是说这是 Keras 之中的一个 API 。由于之前已经学习过早停回调,这节课我们来学习一下其他的几个常用的回调:模型保存回调:tf.keras.callbacks.ModelCheckpoint;学习率回调;tf.keras.callbacks.LearningRateScheduler;自定义回调:tf.keras.callbacks.CallBack。对于回调的使用方法,也是非常简单的,假设以下的数组之中定义了我们所需要的全部回调函数:callbacks = [......]那么我们在使用回调的时候,之中只需要在训练函数中指定回调即可:model.fit(..., ..., callbacks=callbacks)对于要介绍的回调,我们会首先给出介绍,然后再在统一的代码之中示例使用。

3.2 可选链与函数调用

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的。当函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回 undefined 而不是抛出一个异常。var person = {}var name = person.getName?.();注意:如果属性名不是函数也会报错,可选链只会判断属性是否有效,而不能判断属性的类型。var person = {getName: ''}var name = person.getName?.();// Uncaught TypeError: person.getName is not a function

3.4 函数调用时传参问题

在函数调用时经常会向函数中传递参数,但是,当我们的参数是数组中的项时,我们需要把数组中的每一项取出来,然后传入函数中,这样显得很麻烦,能不能有个方式直接把数组传入进去呢?首先我们看个求和的例子:function sum(x, y) { return x + y;}console.log(sum(1, 2)); // 3const data = [1,2];console.log(sum(data[0], data[1])); // 3上面的 sum 是一个求和函数,接受两个参数,我们可以在调用时直接传递 2 个参数。但这个时候我们希望求 data 数组中的和,这个时候只能取出 data 中的每一项值传递到函数中去,这样无疑是一个很笨的方法,在 ES5 的时候可以使用 apply() 对函数进行间接的调用解决这个问题。function sum(x, y, z) { return x + y + z;}const data = [1,2,3];console.log(sum.apply(null, data)); // 6使用 apply() 的方法是解决了这个问题,但是可能会使我们理解代码增加了难度。有了 ES6 的展开语法,这个问题就会轻而易举地解决了。function sum(x, y, z) { return x + y + z;}const data = [1,2,3];console.log(sum(...data)); // 6上面的方法使用展开语法把 data 数组中的每一项进行展开,成为 sum 函数中的三个参数。

5.1 Java 调用 Kotlin 中的实化类型参数函数限制

明确回答 Kotlin 中的实化类型参数函数不能在 Java 中的调用,我们可以简单的分析下,首先 Kotlin 的实化类型参数函数主要得益于 inline 函数的内联功能,但是 Java 可以调用普通的内联函数但是失去了内联功能,失去内联功能也就意味实化操作也就化为泡影。故重申一次 Kotlin 中的实化类型参数函数不能在 Java 中的调用。

2.3 第二个参数 —— 回调函数

在 Array.from 中第二个参数是一个类似 map 函数的回调函数,该回调函数会依次接收数组中的每一项作为传入的参数,然后对传入值进行处理,最得到一个新的数组。Array.from(obj, mapFn, thisArg) 也可以用 map 改写成这样 Array.from(obj).map(mapFn, thisArg)。var arr = Array.from([1, 2, 3], function (x) { return 2 * x;});var arr = Array.from([1, 2, 3]).map(function (x) { return 2 * x;});//arr: [2, 4, 6]上面的例子展示了,Array.from 的参数可以使用 map 方法来进行替换,它们是等价的操作。

JavaScript 函数

在 JavaScript中,函数是头等 (first-class) 对象,因为它们可以像任何其他对象一样具有属性和方法。它们与其他对象的区别在于函数可以被调用。简而言之,它们是 Function 对象。(MDN)函数就是一段代码片段,调用函数就是执行函数中的代码。

3.1 函数

函数其实是一段 JavaScript 代码,调用函数就会执行函数中的代码。使用 function 关键字就可以定义一个函数,简单的函数语法如下:function 函数名(参数) { 函数体; return 返回值;}var ret = 函数名(参数1) // 调用函数函数名就是函数的名字,在调用函数的时候会被使用到。参数则是传递给函数的数据,函数内部可以访问到传进来的参数。return 则标志着函数的结束,返回值会被作为结果进行返回。function add(arg1, arg2) { var sum = arg1 + arg2; return sum;}var num1 = add(1, 2);var num2 = add(4, 2);console.log(num1); // 输出:3console.log(num2); // 输出:6上面这个例子就是声明了一个名为 add 的函数,其功能就是把两个参数求和并返回。可以看到函数让代码更加有 意义,调用 add 函数的地方可以很好的理解这里是在做求和操作,同时提高了代码的复用率。

Kotlin 函数

这篇文章我们将一起来认识 Kotlin 的函数,Kotlin 中的函数可以说比 Java 中的函数更优,解决 Java 函数调用中存在一些问题。此外还会介绍 Java 中没有的函数,比如顶层函数、中缀函数等等。

1.1 java中函数调用存在什么问题?

在 Java 开发程序的过程中,经常会去调用一些方法,有的人设计方法的参数有很多,而且参数命名有时候还不太规范(不能达到见名知意),并且设计的时候几个相同的参数类型还是挨着的。这个实际上给调用者带来了很大的困扰和麻烦,谨慎的程序猿会定位到这个函数定义的地方,大概看了下参数的调用的顺序以及每个参数的函数。特别当这个方法被打包成一个 lib 的时候,查看就比较麻烦。而且相同类型参数挨着很容易对应错。一起看个例子: // A开发的函数接口顺序(调用者必须按照这个顺序传) static String joinToString(List<Integer> nums, String prex, String sep, String postfix) { StringBuilder builder = new StringBuilder(prex); for (int i = 0; i < nums.size(); i++) { builder.append(i); if (i < nums.size() - 1) { builder.append(sep); } } builder.append(postfix); return builder.toString(); } // B开发的函数接口顺序(调用者必须按照这个顺序传) static String joinToString(List<Integer> nums, String prex, String postfix, String sep) { StringBuilder builder = new StringBuilder(prex); for (int i = 0; i < nums.size(); i++) { builder.append(i); if (i < nums.size() - 1) { builder.append(sep); } } builder.append(postfix); return builder.toString(); } //假如现在修改一下,拼接串前缀或分隔符,仅从外部调用是无法知道哪个参数是前缀、分隔符、后缀 public static void main(String[] args) { //后面传入的三个字符串顺序很容易传错,并且外部调用者如果不看具体函数定义根本很难知道每个字符串参数的含义,特别公司中一些远古代码,可能还得打成库的代码,点进去看实现肯定蛋疼。 //调用A的接口 System.out.println(joinToString(Arrays.asList(new Integer[]{1, 3, 5, 7, 9}), "<", ",", ">")); //调用B的接口 System.out.println(joinToString(Arrays.asList(new Integer[]{1, 3, 5, 7, 9}), "<", ">", ",")); }其实针对以上问题,AndroidStudio 的给我们做了个很好的优化提示,但是在 3.0 之前是没有这个提示的,如图:实际上 jetBrains 实际上把这个提示是直接融入了他们开发的Kotlin语言中,力图开发者尽量让在语法的层面上少犯错误,少走弯路,更加注重于代码本身的实现;让你直接在语法的层面上就更加明确,减少疑惑性。

1. 用于调用函数表达式

当想让一个函数立即实行的时候,需要让 JavaScript 将一个函数识别为表达式,void 关键字就能起到这个作用。void function() { alert('马上执行!冲冲冲!');}();但有局限性,如果需要获取到函数的返回值,就不能使用 void。var num1 = 1;var num2 = 2;var result = void function(number1, number2) { return [number1 + number2, number1 * number2];}(num1, num2);result.forEach(function(res) { console.log(res);});如这个例子,函数返回了两数之和与两数之积的结果,但因为 void 关键字,实际 result 变量被赋值为 undefined,导致程序无法正常执行。

1. 使用 Function 创建函数

Function 在被当作构造函数调用的时候,可以用来创建函数。var fn = new Function(函数参数1, 函数参数2, ..., 函数参数n, 函数体);函数体是一个字符串,字符串的内容是就是函数调用时候被执行的语句。var fn = new Function('a', 'b', 'return a + b');var result = fn(1, 3);console.log(result); // 输出:4将上面创建函数的方式“翻译”成常用的创建方式可以是:var fn = function(a, b) { return a + b;};var result = fn(1, 3);console.log(result); // 输出:4对比一下就很好理解使用 new Function 时候所传递的参数的含义了。

2.2 回调函数几乎都用到了闭包的特性

回调函数通常会用到上层作用域的变量,然后在某一情况下进行调用。var fn = function(cb) { console.log('异步操作开始'); setTimeout(function() { console.log('异步操作结束'); cb(); }, 1000);};var obj = { flag: false,};fn(function() { obj.flag = true; console.log(obj);});很明显,这里的回调函数就是用到了闭包的特性。所以闭包其实很常用,结合日常的这些场景能更好的理解闭包。

3.3 调用 render 函数返回

HTML 文本或者模板文件。其实,通过查看 Django 的源代码,可以看到 render 函数会调用 loader.render_to_string() 方法将 html 文件转成 string,然后作为 content 参数传递给 HttpResponse 类进行实例化:# django/shortcuts.pydef render(request, template_name, context=None, content_type=None, status=None, using=None): """ Return a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments. """ content = loader.render_to_string(template_name, context, request, using=using) return HttpResponse(content, content_type, status)它的用法如下:# 第一步,在django工程中准备一个静态文件,放到templates目录下(django-manual) [root@server first_django_app]# cat templates/index.html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h1>这是首页</h1></body></html># 第二步,在first_django_app/setting.py文件,指定静态资源的目录(django-manual) [root@server first_django_app]# cat first_django_app/settings.py...TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 指定项目目录下的templates目录 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]...# 第三步,添加视图函数以及URLconf,位置first_django_app/urls.pydef index(request, *args, **kwargs): return render(request, "index.html")urlpatterns = [ path('admin/', admin.site.urls), path('index/', index),]就这样一个简单的配置,我们请求 /index/ 路径时,会返回 index.html 文件内容:[root@server ~]# curl "http://127.0.0.1:8881/index/"<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h1>这是首页</h1></body></html>另一方面,index.html 还可以是一个模板文件,我们通过 render 函数最后会将该模板文件转成一个完整的 HTML 文件,返回给客户端:# index.html(django-manual) [root@server first_django_app]# cat templates/index.html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h1>{{ title }}</h1><p>{{ content }}</p></body></html># 修改 urls.py 中的视图函数(django-manual) [root@server first_django_app]# cat first_django_app/urls.py...def index(request, *args, **kwargs): return render(request, "index.html", {"title":"首页", "content": "这是正文"}) ...最后请求结果可以看到完整的 HTML 文本:[root@server ~]# curl "http://127.0.0.1:8881/index/"<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><h1>首页</h1><p>这是正文</p></body></html>

2.5 递归函数

Shell 支持递归函数,递归函数也就是自己调用自己,即在函数体内部又一次调用函数自己,例如:[root@master func]# cat recursion.sh #!/bin/bashfunction myecho() { echo "$(date)" sleep 1 myecho inner}myecho[root@master func]# bash recursion.sh Sat Mar 28 13:14:38 CST 2020Sat Mar 28 13:14:39 CST 2020Sat Mar 28 13:14:40 CST 2020Sat Mar 28 13:14:41 CST 2020Sat Mar 28 13:14:42 CST 2020...如上就是一个递归函数,在函数体内部又调用了函数 myecho,在执行的时候就会陷入无限循环。

2. fork 函数

面试官提问: Linux 系统中的 fork 函数是什么,有什么用途?题目解析:首先从定义上看,fork 函数的作用是在一个进程的基础上创建新的进程,原有的进程被定义为父进程,新的进程被定义为子进程。在 C 语言中调用 fork() 函数即实现 fork 功能,示例:#include<unistd.h> //包含fork函数的头文件pid_t fork(void); //fork的返回类型为pid_t,我们可以看成int类型认识一个函数,需要从函数的定义入手,了解函数做了什么事情,入参是什么,出参是什么。我们以 C 语言实现的一个典型的 fork 的程序入手,示例:#include <unistd.h>#include <stdio.h> int main (){ pid_t fpid; int count = 0; fpid = fork(); if (fpid == 0) { //返回值是0,说明是子进程 printf("i am the child process, process id is %d\n", getpid()); count++; } else if(fpid > 0) { //返回值>0,说明是父进程 printf("i am the parent process, process id is %d\n", getpid()); count++; } else { //返回值<0,说明fork发生异常 printf("fork encounter exception, process id is %d\n", getpid()); } //打印计数器 printf("after fork, counting result : %d\n", count); return 0;}在 MacOS 系统上编译运行案例示例代码,运行结果如下图。test.c 编译执行结果如果是不了解函数原理的前提下,仅仅从代码层面分析,在调用 fork() 函数之后,代码会进入 if-else 判断逻辑,在控制台输出一条语句,然后在控制台打印计数器的数值。但是从真正执行的结果来看,这两个打印动作都分别执行了两次,并不符合我们的预期。fork 之后的代码逻辑被执行了两次,而且两次进入的不同的分支,所以重点在于 fork 函数到底有啥作用。按照定义、入参和出参三步走的框架,首先是分析函数的定义,调用 fork 函数之后发生了什么事情:(1)分配内存:分配新的内存空间给子进程;(2)拷贝数据:拷贝父进程的数据结构给子进程;(3)加入列表:将新生成的子进程添加到操作系统的进程列表;(4)返回结果:fork 函数调度并且返回。然后是分析 fork 函数的入参,fork 函数入参是 void,也就是自动同步进程的上下文,不需要手动声明。最后是分析 fork 函数的出参,fork 函数和程序员日常接触的函数不同,我们在 C 或者 Java 中定义的函数只会有一个返回值,fork 函数则是调用一次,返回二次。调用方(例如上述案例的 main 函数)根据返回值的不同判断处于父进程还是子进程。(1)返回值 < 0:调用失败,一般是因为操作系统中的进程个数达到上限或者内存不足以分配给新的进程;(2)返回值 = 0:调用成功,并且处于子进程;(3)返回值 > 0:调用成功,并且处于父进程。现在就不难理解,从调用 fork() 函数,代码实际上是被父子进程分别执行了一次,父进程的进程 id 是 52331,子进程的进程 id 是 52332。在掌握原理之后,我们继续探究 fork 函数的应用场景。fork 函数的本质在原有的进程基础上创建一个新的进程,所以在网络通信中使用较多,例如在客户端发送一个 HTTP 请求打到服务器时,服务器进程 fork 出一个子进程用于处理单个请求,父进程则继续等待其他的请求。

2.3 函数参数

上述我们了解了函数的定义,在其中无参函数调用即调用函数名即可,对于有参函数,需要传递一定的参数来执行对应的操作,函数的参数和脚本的参数类型及用法一致,在此我们简单回顾下,看参数在函数中都有哪些分类,及该如何使用。2.3.1 位置参数位置参数顾名思义,就是传递给函数参数的位置,例如给一个函数传递一个参数,我们可以在执行 Shell 脚本获取对应位置的参数,获取参数的格式为:$n。n 代表一个数字,在此需要注意与脚本传递参数不一样,$0 为依旧为脚本的名称,在函数参数传递中,例如传递给函数的第一个参数获取就为 $1,第 2 个参数就为 $2, 以此类推……,需要其 $0 为该函数的名称。例如:[root@master func]# cat f1.sh #!/bin/bashfunction f1() { echo "函数的第一个参数为: ${1}" echo "函数的第二个参数为: ${2}" echo "函数的第三个参数为: ${3}"}# 调用函数f1 shell linux python go[root@master func]# bash f1.sh 函数的第一个参数为: shell函数的第二个参数为: linux函数的第三个参数为: python我们可以看到传递给 f1 函数共 4 个位置参数,在结果输出中可以看到由于函数体内部只对三个参数进行了处理,后续的参数也就不再处理了。2.3.2 特殊参数在 Shell 中也存在特殊含义的参数如下表:变量含义$#传递给函数的参数个数总和$*传递给脚本或函数的所有参数,当被双引号 " " 包含时,所有的位置参数被看做一个字符串$@传递给脚本或函数的所有参数,当被双引号 " " 包含时,每个位置参数被看做独立的字符串$?$? 表示函数的退出状态,返回为 0 为执行成功,非 0 则为执行失败示例:[root@master func]# cat f1.sh #!/bin/bashfunction fsum() { echo "函数第一个参数为: ${1}" echo "函数第二个参数为: ${2}" echo "函数第三个参数为: ${3}" echo "函数的参数总数为: ${#}" echo "函数的参数总数为: ${@}" local sum=0 for num in ${@}; do let sum=${sum}+${num} done echo "计算的总和为: ${sum}" return 0}# 调用函数fsum 10 20 1 2echo $?[root@master func]# bash f1.sh 函数第一个参数为: 10函数第二个参数为: 20函数第三个参数为: 1函数的参数总数为: 4函数的参数总数为: 10 20 1 2计算的总和为: 330如上可以看到特殊参数与 Shell 脚本传递参数一样。Tips:局部变量需要特别声明在函数内部利用 local 关键字来声明。

Python 中的函数参数

在通常情况下,定义函数时,函数的参数个数是预先确定的。例如,编写计算两个数相加的函数 add(a, b),代码如下:def add(a, b): return a + bsum = add(1, 2) 在第 1 行,定义了函数 add,函数有两个参数,第 1 个参数是 a,第 2 个参数是 b在第 2 行,计算参数 a 和 参数 b 的累加和,通过 return 语句将计算结果返回给调用者在第 4 行,通过 add(1, 2) 调用函数 add将整数 1 传递给第 1 个参数 a将整数 2 传递给第 2 个参数 b传入的两个整数按照位置顺序依次赋给函数的参数 a 和 b,参数 a 和参数 b 被称为位置参数。在 Python 中,调用函数时,根据函数定义的参数位置来传递参数,要求传递的参数与函数定义的参数两者一一对应,如果 “传递的参数个数” 不等于 “函数定义的参数个数”,运行时会报错,例如:def add(a, b): return a + bsum = add(1, 2, 3)在第 1 行,定义了函数 add,函数有 2 个参数在第 4 行,通过 add(1, 2, 3) 调用函数 add,传递了 3 个参数因为 “传递的参数个数” 不等于 “函数定义的参数个数”,运行时报错如下:C:\> python add.pyTraceback (most recent call last): File "error.py", line 4, in <module> sum = add(1, 2, 3)TypeError: add() takes 2 positional arguments but 3 were given在第 5 行,运行时提示:函数 add 有 2 个位置参数,但是调用时传递了 3 个位置参数。

3.2 函数传递

顾名思义,参数传递就是在函数外部进行参数的传入,由于函数部分在后续有专门章节详解,在此我们就以一个简单的示例进行说明。函数传递与脚本传递非常类似,只是在调用函数的时候进行传递位置参数即可,例如:[root@master Shell_args]# cat args_fun.sh #!/bin/bash# 函数定义function show_args() { echo "第一个参数为: $1" echo "第二个参数为: $2" echo "脚本名称为: $0"}# 函数调用show_args go Shell[root@master Shell_args]# bash args_fun.sh 第一个参数为: go第二个参数为: Shell脚本名称为: args_fun.sh在示例中,我们可以看到没有通过在脚本外部进行参数传递,而是在调用 show_args 函数的时候传入来两个参数。

5.7 颜色函数

Sass 中提供了非常非常多的颜色函数用来处理颜色值,它们很多需要你具有专业的调色及配色知识才能发挥出作用,所以本节我们不讲的那么复杂,本节内容中我们只讲几种常见的、比较简单的颜色函数,其他特别复杂的用于调色的函数在以后你可以再慢慢研究。5.7.1 用于获取通道色值的函数Sass 提供了可以获取一个色值中红色通道、绿色通道和蓝色通道色值的函数,它们分别是 red($color) 、green($color) 和 blue($color)。你可能还不太了解这三种通道是什么,不要紧,只要知道这三种函数和它的使用就可以。我们举例看下:blue(#BA55D3) //=> 211red(#BA55D3) //=> 186green(#BA55D3) //=> 855.7.2 saturate($color, $amount)saturate($color, $amount) 函数用于调整 $color 的饱和度,第 1 个参数 $color 是一个颜色值,第 2 个参数是 0% ~ 100% 之间的百分数,其返回值也是一个颜色值。saturate(#BA55D3, 20%) //=> #c740e85.7.3 scale-color(…)这是一个非常强大的颜色函数,它接收很多个参数,可以调整一个色值的很多属性,包括这个颜色的红、绿、蓝通道,以及亮度等等,我们只能举例来直观的看下:scale-color(#BA55D3, $red: 15%) //=> #c455d3 调整红色通道scale-color(#BA55D3, $blue: 15%) //=> #ba55da 调整蓝色通道scale-color(#BA55D3, $lightness: -10%, $saturation: 10%) //=> #b338d2 调整亮度和饱和度scale-color(#BA55D3, $alpha: -30%) //=> rgba(186, 85, 211, 0.7) 调整不透明度通过上面的例子可以看到颜色函数提供了非常强大的用于调色的函数,驾驭它的前提是你要有非常丰富的调色知识以及一定的美术基础。在实际的项目中我们非常少的用到颜色函数,因为一般都是由公司的 UI 设计师来进行调色,所以作为入门教程,你只需要了解 Sass 中的颜色函数就好。

1. 函数的定义和使用

Go 语言中,通过 func 关键字来声明和定义函数。Go 语言和 C 语言不同,Go 语言函数的声明和定义是一起的,不存在先声明在定义,且声明时不分前后均可互相调用。代码示例package mainimport "fmt"func print(s string) { fmt.Println(s)}func main() { print("Hello Codey !")}第 5 行:声明并定义一个名叫 print 的函数,函数接收一个 string 类型的参数;第 6 行:函数体。一个输出接收进来参数的值的语句;第 9 行:声明并定义了一个叫main的函数。Go 语言中程序的入口就时 main 函数,所有的程序都以main 函数作为入口;第 10 行:调用 print 函数,传入参数"Hello Codey !"。执行结果:

5. 使用函数时的注意事项

如果一个函数没有使用 return 语句,则它默认返回 undefined。调用函数时,传递给函数的值被称为函数的 实参(值传递),对应位置的函数参数被称为 形参。在函数执行时, this 关键字并不会指向正在运行的函数本身,而是 指向调用函数的对象。arguments 对象是所有(非箭头)函数中都可用的 局部变量。你可以使用 arguments 对象在函数中引用函数的参数。

2. 函数提升

函数也会提升,函数的提升会把整个函数放到最前。fn('咕咕咕');function fn(str) { console.log(str);}这段代码可以被正常执行,函数也能被正常调用,因为在生成执行上下文阶段,整个函数会提升到最前面。这个规则只对函数声明的方式声明的函数有效,如果使用的是函数表达式,那就会走变量提升的规则。console.log(fn); // 输出:undefinedfn('咕咕咕'); // 抛出异常 TypeError: fn is not a functionvar fn = function(str) { console.log(str);};可以看到 fn 能被访问到,已经声明了,但不能作为函数调用,这说明 fn 走了变量提升的机制。在执行上下文生成的阶段,函数会比变量更早的进行提升,也就是说函数相比变量,更加靠前。函数在调用时也会生成函数级别的执行上下文,这也就意味着提升这个特性也会在函数执行前发生。

4. 钩子函数

上面我们介绍了 Vue.directive 第二个参数接收的是钩子函数对象,这些钩子函数都是可选的。接下来我们详细介绍这几个钩子函数的作用:bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置;inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中);update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下);componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用;unbind:只调用一次,指令与元素解绑时调用。

5.4 Introspection函数

Introspection函数实际在样式中写的非常少,一般用于代码的调试以及做一些判断。这里我们只举几个例子来看下:type-of(10px) //=> number 用于判断数据的类型,返回数据的类型type-of(10px 20px 30px) //=> list 用于判断数据的类型,返回数据的类型variable-exists("a") //=> false 用于判断当前范围中一个变量是否存在,这里是判断变量 $a 是否存在meta.module-variables($module) //=> 用于返回一个模块中定义的所有变量call($function, $args...) //=> 使用 $args 调用 $function,这个很像 javascript 中的 call上面举了几个 Introspection函数的例子,这类函数一般很少直接用到样式中,入门实战你只需要了解有这类函数就可以,刚开始很少会直接应用。

2.1 numpy.random.randn函数

numpy.random.randn 函数可以用来创建一个指定维度的、符合标准正态分布(以0为均值、1为标准差)的浮点数(数组)。函数调用方法如下:numpy.random.randn(d0, d1, ..., dn)构造函数接受的参数详解如下:参数描述d0, d1, …, dn表征生成数组的维数,若不指定则默认返回一个浮点数。案例最简单的情况,当不指定任何参数的时候,生成 0-1 之间的随机浮点数:np.random.randn()Out: -0.12290005859272764相应地,也可以指定产生一个固定维度的数组,例如希望生成一个指定维度为 3×2,服从 “0-1” 均匀分布的数组,可以用如下语句顺利实现:np.random.randn(3, 2)Out: array([[-0.57391562, 0.06713778], [ 1.06383981, -0.36837876], [ 1.21325918, 2.83456824]])可以发现,numpy.random.randn 函数和 numpy.random.rand 函数的调用规则非常相似,不同的地方在于产生随机数的分布不一样。

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号