javascript函数式

by rajaraodv

通过rajaraodv

JavaScript中的函数式编程—结合实际示例(第1部分) (Functional Programming In JavaScript — With Practical Examples (Part 1))

Functional Programming(FP) can change the way you program for the better. But it’s hard to learn and many posts and tutorials don’t go into details like Monads, Applicative and so on and don’t seem to use practical examples to help us use powerful FP techniques on a daily basis. That’s why I thought of writing a post to make it easier to use FP techniques.

功能编程(FP)可以更好地改变您的编程方式。 但是这很难学习,许多帖子和教程没有涉及Monads,Applicative等细节,也似乎没有使用实际示例来帮助我们每天使用强大的FP技术。 这就是为什么我想到写一篇文章以使使用FP技术更容易的原因。

Please Note: The emphasis in this blog is on WHY xyz feature is required than just WHAT xyz feature is.

请注意:本博客的重点是WHYWHAT只是XYZ的特点是需要某某功能。

In Part 1, you’ll learn Functional Programming basics, Currying, Pure Functions, “Fantasy-land” specs, “Functors”, “Monads”, “Maybe Monads” and “Either Monads” via couple of examples.

在第1部分中,您将通过一些示例学习函数式编程基础知识,Currying,纯函数,“幻想领域”规范,“ Functors”,“ Monads”,“ Maybe Monads”和“ Either Monads”。

功能编程 (Functional Programming)

Functional Programming is a style of writing programs by simply composing a set of functions.

函数式编程是一种通过简单地组合一组函数来编写程序的样式。

Essentially, FP asks us to wrap virtually everything in functions, write lots of small reusable functions and simply call them one after the other to get the result like: (func1.func2.func3) or in a compose fashion, like: func1(func2(func3())).

从本质上讲,FP要求我们将几乎所有内容包装在函数中,编写许多小的可重用函数,然后简单地一个接一个地调用它们,以得到如下结果:( func1.func2.func3 )或以一种组合方式,例如: func1(func2) (func3()))

But in order to actually write programs in this style, functions need to follow some rules and overcome some challenges like the ones mentioned below:

但是,为了以这种方式实际编写程序,函数需要遵循一些规则并克服一些挑战,例如以下所述:

FP挑战: (The FP Challenges:)

If everything can be done by composing a set of functions..

如果一切都可以通过组合一组函数来完成。

  1. How can we handle if-else condition? (Hint: “Either” Monad)

    我们如何处理if-else条件? ( 提示:“两个” Monad )

  2. How can we handle Null Exceptions (Hint: “Maybe” Monad)?

    我们如何处理Null异常( 提示:“ Maybe” Monad )?

  3. How to ensure functions are truly “reusable” and can be reused anywhere, (Hint: Pure functions, referential transparency)?

    如何确保函数真正“可重用”并且可以在任何地方重用( 提示: 纯函数, 引用透明性 )?

  4. How to ensure the data we pass to it is unchanged so that we can reuse the data elsewhere(Hint: Pure functions, immutability)?

    如何确保传递给它的数据是不变的,以便我们可以在其他地方重用数据( 提示: 纯函数,不变性 )?

  5. If a function is taking multiple values but chaining can only pass a single value, how can we still make it part of a chain (Hint:currying” and “higher-order functions”)?

    如果一个函数采用多个值,但是链接只能传递一个值,那么我们如何仍使其成为链的一部分( 提示:currying”和“ higher-order functions” )?

  6. and more..<add your question here>.等等.. <在这里添加您的问题>。

FP解决方案: (The FP Solution:)

In order to deal with all these challenges, fully Functional Programming languages like Haskell provides various tools and concepts from mathematics like “Monads”, “Functors” and so on out-of-the-box.

为了应对所有这些挑战,像Haskell这样的全功能编程语言提供了开箱即用的数学等各种工具和概念,例如“ Monads”,“ Functors”等。

While JavaScript doesn’t provide many of the tools out-of-the-box, thankfully it has enough FP features that allows people to write libraries.

尽管JavaScript并没有提供许多现成的工具,但值得庆幸的是,它具有足够的FP功能,使人们可以编写库。

幻想土地规格和FP库 (Fantasy-Land Specs And FP Libraries)

Libraries that want to provide features like Functors, Monads and so on, need to implement functions/classes that follow some specs in order to provide functionalities like they are in languages like Haskell.

想要提供Functors,Monads等功能的库,需要实现遵循某些规范的函数/类,才能提供类似Haskell这样的语言的功能。

Fantasyland specs is one of the prominent specs that explains how each JS functions/classes should behave.

Fantasyland规范是解释每个JS函数/类应如何表现的重要规范之一。

The above picture shows all the specs and their dependencies. Specs are essentially laws and similar to “interfaces” in Java. From JS perspective, you can think of specs as “classes” or constructor functions that implement some methods like (map, of, chain and so on) according to the specification.

上图显示了所有规格及其依赖性。 规范本质上是法律,类似于Java中的“接口”。 从JS的角度来看,您可以将规范视为“类”或构造函数,它们可以根据规范实现某些方法,例如( mapofchain等)。

For example:

例如:

A JS class is a “Functor” if it implements a “map” method. And that map method must work as per spec (ps:This is simplified version and there are more rules).

如果JS类实现了“地图”方法,则它就是“函数器”。 并且该map方法必须按照规范运行(ps:这是简化版本,并且有更多规则)。

Similarly, a JS class is an “Apply Functor” if it implements “map” and “ap” functions as per spec.

同样,如果JS类按照规范实现“ map”和“ ap”功能,则它是“ Apply Functor”。

Similarly, a JS class is a “Monad” (aka Monad Functor), if implements requirements of “Functor”, “Apply”, “Applicative”, “Chain” and “Monad” itself (because of the dependency chain).

同样,如果实现了“ Functor”,“ Apply”,“ Applicative”,“ Chain”和“ Monad”本身(由于依赖链)的要求,则JS类是“ Monad”(又名Monad Functor)。

Note: The dependency may look like inheritance but not necessarily. For example: Monad implements both “Applicative” and “Chain” specs (in addition to others).

注意:依赖性可能看起来像继承,但不一定如此。 例如:Monad同时实现“适用”和“链式”规范(以及其他规范)。

符合幻想土地规范的库 (Fantasy-Land Spec compliant Libraries)

There are several libraries that implement FL spec. For example: monet.js, barely-functional, folktalejs, ramda-fantasy (based on Ramda), immutable-ext (based on ImmutableJS), Fluture and more.

有几个实现FL规范的库。 例如: monet.js, 勉强官能 , folktalejs , ramda幻想 (基于Ramda), 不可变-EXT (基于ImmutableJS), Fluture等等。

我应该使用哪些图书馆? (What Libraries Should I Use?)

Libraries like lodash-fp, ramdajs, only enable you to start writing in FP style. But they don’t provide functions to use key mathematical concepts like Monads, Functors, Foldables to actually solve real-world problems.

lodash-fp , ramdajs之类的库仅使您可以开始以FP样式编写。 但是它们没有提供使用诸如Monads,Functors,Foldables之类的关键数学概念来实际解决实际问题的功能。

So, in addition to them you’ll have to use one of the libraries that follow fantasy-land spec. Some such libraries are: monet.js, barely-functional, folktalejs, ramda-fantasy (based on Ramda), immutable-ext (based on ImmutableJS), Fluture and more.

因此,除了它们之外,您还必须使用遵循幻想世界规范的库之一。 此类库包括: monet.js, 几乎不起作用的民俗故事 , ramda-fantasy (基于Ramda ), immutable-ext (基于ImmutableJS), Fluture等。

Note: I’m using ramdajs and ramda-fantasy

注意:我使用的是ramdajsramda-fantasy

OK, now that we know the basics, Let’s see some practical examples and learn various FP features and techniques through those examples.

好的,现在我们已经了解了基础知识,让我们看一些实际示例,并通过这些示例学习各种FP功能和技术。

示例1 —处理空检查 (Example 1 — Dealing With Null Checks)

Topics covered: Functors, Monads, Maybe Monad, Currying.

涵盖的主题:函子,单子,也许单子,咖喱。

Use-case: We want to show different index webpage depending on the user’s “primary” language (inside user’s prefs, see below). And we need to write getUrlForUser that returns appropriate URL from the list of URLs(indexURLs) for the user’s (joeUser) primary language(“spanish”).

用例:我们希望根据用户的“ 主要” 语言显示不同的索引网页(在用户的偏好内,请参见下文)。 而且我们需要编写getUrlForUser返回适当的 网址 从用户( joeUser ) 主要 语言 (“ spanish” )的URL( indexURLs )列表中。

The problem is: the primary language could be null. The user itself could be null (not logged in). The primary language might not be available in our list of indexURLs. So we’ll have to take care of lots of “nulls” or “undefined”.

问题是:主要语言可能为空。 用户本身可以为null(未登录)。 我们的indexURL列表中可能没有主要语言。 因此,我们将不得不处理很多“空值”或“未定义”。

解决方案(相对于FP): (Solution (Imperative Vs FP):)

PS: Don’t worry if the FP version looks hard to understand, I’ll cover them step-by-step later in this post.

PS:不用担心FP版本看起来很难理解,我将在本文的后面逐步介绍它们。

OK, Let’s first understand several FP concepts and techniques used in this solution.

好的,让我们首先了解该解决方案中使用的几种FP概念和技术。

函子 (Functors)

Any class(or construction function) or a datatype that stores a value and implements “map” method is called a “Functor”.

任何存储值并实现“ map”方法的类(或构造函数)或数据类型都称为“ Functor”。

For example: An Array is a “Functor”. Because an Array can store values and has “map” method that allows us to map a function to the values it’s storing.

例如:数组是“ Functor”。 因为数组可以存储值,并且具有“ map”方法,该方法允许我们将函数映射到其存储的值。

const add1 = (a) => a+1;
let myArray = new Array(1, 2, 3, 4); //store values
myArray.map(add1) // -> [2,3,4,5] //applies functions

Let’s write our own Functor “MyFunctor”. It’s simply a JS class (constructor function) that stores some value and implements a “map” method. This “map” method applies the function to the stored value and then creates a new Myfunctor from the result and returns that new MyFunctor.

让我们编写我们自己的Functor“ MyFunctor”。 它只是一个JS类(构造函数),它存储一些值并实现“ map”方法。 此“映射”方法将函数应用于存储的值,然后根据结果创建一个新的Myfunctor,并返回该新的MyFunctor。

PS: Functors also need to implement other specs (see Fantasyland specs) in addition to “map” but I’m not going to cover them here.

PS:Functors除了“地图”之外,还需要实现其他规范(请参阅Fantasyland规范 ),但在此不做介绍。

单音 (Monads)

Monads are also Functors, i.e. they have “map” method but implements more methods than just “map”. If you look at the spec dependency graph again, you’ll see that also need to implement various other features in different specs like: “Apply” (ap method), “Applicative” (ap and of method), and “Chain” (chain method).

Monad也是Functor,即它们具有“ map ”方法,但实现的方法不仅仅是“ map”。 如果再次查看规格依赖关系图,您还将看到还需要在不同规格中实现各种其他功能,例如:“ Apply ”( ap方法),“ Applicative ”( ap and of方法)和“ Chain ”( 连锁法)。

Simplified Explanation: In JS, Monads are classes or constructor functions that store some data and implements “map”, “ap”, “of” and “chain” methods that do something with the stored data as per spec.

简化说明: 在JS中,Monads是存储某些数据并实现“ map”,“ ap”,“ of”和“ chain”方法的类或构造函数,这些方法根据规范对存储的数据进行处理。

Below is a sample implementation so you get an idea of the internals of the Monad.

下面是一个示例实现,因此您可以了解Monad的内部原理。

Now, the generic Monads are not typically used but more specific and more useful Monads like “Maybe Monad” or “Either Monad” are often used in FP programming. So, let’s take a look at “Maybe Monad”.

现在,一般不使用通用Monad,但是在FP编程中经常使用更具体,更有用的Monad,例如“ Maybe Monad”或“ Either Monad”。 因此,让我们看一下“也许是Monad”。

“Maybe” Monad

“也许”莫纳德

A “Maybe” Monad is a class that implements Monad spec. But the special thing about Monad is that it takes care of “null” or “undefined” values.

“也许” Monad是实现Monad规范的类。 但是Monad的特别之处在于它可以处理“ null”或“ undefined”值。

Specifically, if the data stored is a null or undefined, then it’s “map” function doesn’t run the given function at all and there by avoiding any null or undefined issues. It is used in situations where we are dealing with Null values.

具体来说,如果存储的数据为null或未定义,那么它的“ map”函数根本不会运行给定的函数,从而避免了任何null或未定义的问题 。 它用于我们处理Null值的情况。

Below code shows ramda-fantasy’s implementation of Maybe Monad. It creates an instance of one of the two different sub-classes, Just or Nothing, depending on the value (i.e. useful value V/s null/undefined respectively).

下面的代码显示了ramda-fantasy对Maybe Monad的实现。 它根据值(即有用值V / s分别为null / undefined)创建两个不同子类JustNothing之一的实例。

While both Just and Nothing has similar methods (map, orElse etc), Just’s actually does something but Nothing’s doesn’t do anything.

尽管JustNothing都具有相似的方法(地图,orElse等),但Just确实可以执行某些操作,而Nothing则不执行任何操作。

Give special attention to “map” and “orElse” methods below

特别注意下面的“ map”和“ orElse”方法

Let’s see how to use Maybe monad to deal with “null” checks.

让我们看看如何使用Maybe monad处理“空”检查。

Follow these steps:

跟着这些步骤:

  1. If there any object that might be null or have null properties, create a Monad object out of it.如果存在任何可能为null或具有null属性的对象,请从中创建一个Monad对象。
  2. Use some libraries like ramdajs, that are “Maybe-aware” to access value from w/in the Monad and work on it.使用诸如“ ramdajs”之类的“也许知道”的库从Monad中访问值并对其进行处理。
  3. Provide a default value if the actual value happens to be null (i.e handle Null errors upfront).如果实际值恰好为空(即预先处理空错误),则提供一个默认值。

Currying —(帮助处理全局数据和多参数功能) (Currying — (Helps Dealing With Global Data And Multi-Param Functions))

Topics covered: Pure functions and Composition

涵盖的主题: 纯粹的功能组成

If we want to chain a series of functions together like: func1.func2.func3 or (func1(func2(func3())), all these functions can only receive just one input parameter each. For example, if func2 takes two parameters func2(param1, param2), then we can’t chain it!

如果要将一系列函数链接在一起,例如:func1.func2.func3或(func1(func2(func3())),则所有这些函数只能接收一个输入参数,例如,如果func2接受两个参数func2 (param1,param2),那么我们就无法链接它!

But the practically speaking, many functions take multiple parameters. So how to use them in composition? Solution: “Currying”.

但实际上,许多功能采用多个参数。 那么如何组合使用它们呢? 解决方案:“固化”。

Currying converts a function that takes multiple parameter into a function that takes a single parameter at a time. It wont run the function until all parameters are passed.

Currying会将一个包含多个参数的函数转换为一次包含一个参数的函数。 在传递所有参数之前,它将不会运行该功能。

另外,在访问全局值时,也可以使用Currying。 即使其“纯净”。 (In addition, Currying can also be used in situations when we are accessing global values. i.e. make it “pure”.)

Let’s look at our solution again:

让我们再来看一下我们的解决方案:

示例2 —处理错误引发函数并在发生错误后立即退出 (Example 2— Handling Error Throwing Functions And Exiting Immediately After An Error)

Topics Covered: “Either Monad”

涵盖的主题:“ Monad”

Maybe Monad is great if we have “default” values to replace Null errors. But what about functions that actually need to throw errors? And how to know which function threw the error when we chain multiple error-throwing functions (i.e. we want fast-failure)?

如果我们有“默认”值来代替Null错误,那么Monad也许很棒。 但是实际上需要抛出错误的函数呢? 当我们链接多个抛出错误的函数时,如何知道哪个函数抛出了错误(即我们想要快速失败)?

For example: If we have func1.func2.func3… and if func2 threw an error, we should skip func3 and other future functions and properly show error from func2 so we can handle it.

例如:如果我们有func1.func2.func3…,并且如果func2抛出错误,我们应该跳过func3和其他将来的函数,并正确显示func2的错误,以便我们进行处理。

莫纳德 (Either Monad)

Either Monads are great for dealing with multiple functions when they all can potentially throw error and want to quit immediately after an error so that we can pin-point where the error occurred.

当Monad都可能引发错误并希望在错误发生后立即退出时,Monad都非常适合处理多种功能,以便我们可以查明错误发生的位置。

Use case: For example in the below imperative snippet, we are calculating “tax” and “discount” for items and ultimately displaying showTotalPrice.

使用情况:例如在下面的当务之急片段中,我们正在计算项目 ”和“ 打折 ”,并最终显示showTotalPrice。

Note that the “tax” function will throw error if the price is non-numeric. Similarly, “discount” function will throw error if price is non-numeric and it will also throw error if the item’s price is less than 10.

请注意,如果价格不是数字,那么“ tax ”功能将引发错误。 同样,如果价格为非数字,则“ 折扣 ”功能将引发错误;如果商品的价格小于10,则也会引发错误。

So showTotalPrice has multiple error checks.

因此showTotalPrice具有多个错误检查。

Let’s see how showTotalPrice can be improved by using Either Monad and rewrite everything in FP style.

让我们看看如何通过使用Monad并以FP样式重写所有内容来改善showTotalPrice

Either Monad provides two constructors: “Either.Left” and “Either.Right”. Think of them as subclasses of Either. Both “Left” and “Right” are Monads! The idea is to store errors/exceptions in Left and useful values in Right.

Monad都提供两个构造函数:“ Either.Left”和“ Either.Right”。 将它们视为Either的子类。 “左”和“右”都是Monad! 这个想法是将错误/异常存储在Left中,将有用的值存储在Right中

i.e. create an instance of Either.Left or Either.Right depending on the value. Once we do that we can run map, chain and so on on those values to compose them.

即根据值创建Either.Left或Either.Right的实例。 一旦完成,就可以对这些值运行map,chain等,以组成它们。

While both Left and Right provide “map”, “chain” and so on, Left constructor doesn’t do anything as it stored Errors. Where as the Right constructor implements all the functions as it contains actual result.

虽然LeftRight都提供“ map”,“ chain”等,但是Left构造函数不执行任何操作,因为它存储了Errors。 其中Right构造函数实现所有功能,因为它包含实际结果。

OK, Let’s see how to change our imperative example to FP

好,让我们看看如何将命令式示例更改为FP

Step 1: Wrap return values with Left and Right

步骤1:用左和右包装返回值

Note: “Wrap” means create an instance of some Class. These functions internally call “new” so we don’t have to.

注意:“换行”表示创建某个Class的实例。 这些函数在内部称为“ new”,因此我们不必这样做。

Step 2: Wrap the initial value in Right because it’s a valid value and so we can compose it.

第2步:Right中包装初始值,因为它是有效值,因此我们可以将其组成。

const getItemPrice = (item) =&gt; Right(item.price);

Step 3: Create two functions, one to handle eventual error and another to handle result. And warp them in Either.either (this is from ramda-fantasy.js api).

步骤3:创建两个函数,一个处理最终错误,另一个处理结果。 然后在Either.war中将它们扭曲 (这来自ramda-fantasy.js api )。

Either.either takes 3 params. success handler, an error handler and an "Either" Monad. Either is curried. So we can just pass the handlers for now and pass the Either (3rd param) later.

要么采用3个参数。 成功处理程序,错误处理程序和“任一” Monad。 两者都是咖喱。 因此,我们现在可以只传递处理程序,然后再传递Either(第三个参数)。

Once Either.either receives all 3 params, it passes the 3rd param "Either" to the success handler or error handler depending of if the Either is "Right" or "Left" respectively.

任意一个接收到所有3个参数后,它将分别将第三个参数“ Either”传递给成功处理程序或错误处理程序,具体取决于Either分别是“ Right”还是“ Left”。

const displayTotal = (total) => { console.log(‘Total Price: ‘ + total) };
const logError = (error) => { console.log(‘Error: ‘ + error.message); };
const eitherLogOrShow = Either.either(logError, displayTotal);

Step 4: Use “chain” method to compose multiple error throwing functions. Pass their result to Either.either (eitherLogOrShow) which will take care of passing the result to success handler or failure handler.

第4步:使用“ ”方法构成多个错误抛出函数。 将其结果传递给Either。要么(要么LogOrShow),它将负责将结果传递给成功处理程序或失败处理程序。

const showTotalPrice = (item) => eitherLogOrShow(getItemPrice(item).chain(apply25PercDisc).chain(addCaliTax));

Putting it all together:

放在一起:

Thank you for reading! If you liked the post please ? and share it on Twitter!??

感谢您的阅读! 如果您喜欢这个帖子,请? 并在Twitter上分享!

LATEST: Functional Programming In JS — With Practical Examples (Part 2)

最新: JS中的函数编程—结合实际示例(第2部分)

我的其他帖子 (My Other Posts)

功能编程 (Functional Programming)

  1. JavaScript Is Turing Complete — Explained

    JavaScript正在完善–解释

  2. Functional Programming In JS — With Practical Examples (Part 1)

    JS中的函数式编程—结合实际示例(第1部分)

  3. Functional Programming In JS — With Practical Examples (Part 2)

    JS中的函数式编程—结合实际示例(第2部分)

ES6 (ES6)

  1. 5 JavaScript “Bad” Parts That Are Fixed In ES6

    ES6中修复的5个JavaScript“不良”部分

  2. Is “Class” In ES6 The New “Bad” Part?

    ES6中的“类”是新的“不良”部分吗?

Web包装 (WebPack)

  1. Webpack — The Confusing Parts

    Webpack —令人困惑的部分

  2. Webpack & Hot Module Replacement [HMR] (under-the-hood)

    Webpack和热模块更换[HMR] ( 后台 )

  3. Webpack’s HMR And React-Hot-Loader — The Missing Manual

    Webpack的HMR和React-Hot-Loader —缺少的手册

Draft.js (Draft.js)

  1. Why Draft.js And Why You Should Contribute

    为什么选择Draft.js,为什么要贡献力量

  2. How Draft.js Represents Rich Text Data

    Draft.js如何表示富文本数据

React And Redux: (React And Redux :)

  1. Step by Step Guide To Building React Redux Apps

    构建React Redux应用程序的逐步指南

  2. A Guide For Building A React Redux CRUD App (3-page app)

    构建React Redux CRUD应用程序指南 (3页应用程序)

  3. Using Middlewares In React Redux Apps

    在React Redux应用程序中使用中间件

  4. Adding A Robust Form Validation To React Redux Apps

    向React Redux应用添加强大的表单验证

  5. Securing React Redux Apps With JWT Tokens

    使用JWT令牌保护React Redux应用程序

  6. Handling Transactional Emails In React Redux Apps

    在React Redux应用程序中处理交易电子邮件

  7. The Anatomy Of A React Redux App

    React Redux应用程序剖析

销售队伍 (Salesforce)

  1. Developing React Redux Apps In Salesforce’s Visualforce

    在Salesforce的Visualforce中开发React Redux应用程序

翻译自: https://www.freecodecamp.org/news/functional-programming-in-js-with-practical-examples-part-1-87c2b0dbc276/

javascript函数式

javascript函数式_JavaScript中的函数式编程—结合实际示例(第1部分)相关推荐

  1. javascript函数式_JavaScript中的函数式编程—结合实际示例(第2部分)

    javascript函数式 by rajaraodv 通过rajaraodv JavaScript中的函数式编程-结合实际示例(第2部分) (Functional Programming In Jav ...

  2. javascript函数式_JavaScript中的函数式编程原理

    javascript函数式 After a long time learning and working with object-oriented programming, I took a step ...

  3. javascript闭包_JavaScript闭包教程–带有JS闭包示例代码

    javascript闭包 Closures – many of you JavaScript devs have probably heard this term before. When I sta ...

  4. javascript模块_JavaScript中的模块

    javascript模块 JavaScript模块 (JavaScript Modules) One of the key features of programming fundamentals i ...

  5. javascript 解密_Javascript中的AES加密和Java中的解密

    javascript 解密 AES代表高级加密系统,它是一种对称加密算法,很多时候我们需要在客户端加密一些纯文本,例如密码,然后将其发送到服务器,然后由服务器解密以进行进一步处理.AES加密和解密更加 ...

  6. javascript 常量_JavaScript中的常量

    javascript 常量 JavaScript常数 (JavaScript Constants) Before ES15, the only way to declare variables usi ...

  7. javascript运算符_JavaScript中的按位运算符

    javascript运算符 JavaScript按位运算符 (JavaScript Bitwise Operators) A lot of times you come across some str ...

  8. javascript 排序_JavaScript中的排序方法

    javascript 排序 There are tons of sorting algorithms available like bubble sort, merge sort, insertion ...

  9. javascript运算符_JavaScript中!=或!==运算符之间的区别

    javascript运算符 We can perceive the differences between these two operators as the same difference tha ...

最新文章

  1. 杨海坡:比特币分叉往事
  2. Python 技术篇-用paramiko库实现linux服务器文件下载到winodws本地实例演示
  3. Java网络编程之IP地址和InetAddress类
  4. 计算机省赛教案,《计算机系统的组成》最新 参赛教案.doc
  5. 【转】重新打包DebianISO实现无人应答安装(UEFI+BIOS)
  6. Git 的origin和master解析
  7. Docker 架构原理及简单使用
  8. 2019年12月中国编程语言排行和薪资分析
  9. python tkinter库 pack布局方法调用
  10. 贺利坚老师汇编课程57笔记:CMP和JXXX配合实现条件转移指令if
  11. 宏基电脑安装系统提示acpi错误_电脑常见问题怎么排除 电脑常见问题排除技巧【详解】...
  12. LeetCode 344. Reverse String(反转字符串)
  13. C#从入门到精通之第一篇: C#概述与入门
  14. Ruby之父松本行弘的编程人生
  15. 快速了解idm+油猴插件配合,极速下载(适用于全网)
  16. 【Linux】swp文件
  17. 广东:让“数据跑路”代替“民众跑腿”
  18. 手把手教你用量化做复盘(一)
  19. 计算机网络符号意思,浅析网络语言中的符号网语_计算机网络论文.doc
  20. 仿微信换头像(旋转、还原、裁剪、缩放等)

热门文章

  1. 你是否对它有一种责任感
  2. Python 编写用户登录接口
  3. 网络框架 - 收藏集 - 掘金
  4. oracle 内存分配和调优 总结
  5. RMAN_学习笔记1_RMAN Structure概述和体系结构
  6. OpenCV持久化(二)
  7. NYOJ-49 开心的小明
  8. 强制退出WinForm程序之Application.Exit和Environment.Eixt
  9. Could not apply the stored configuration for monitors 解决办法
  10. 怎么写shell脚本才能不耍流氓?