为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)
by Preethi Kasireddy
通过Preethi Kasireddy
为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门) (Why use static types in JavaScript? (A 4-part primer on static typing with Flow))
As a JavaScript developer, you can code all day long without encountering any static types. So why bother learning about them?
作为JavaScript开发人员,您可以整天编写代码,而不会遇到任何静态类型。 那么,为什么还要花时间去了解它们呢?
Well it turns out learning types isn’t just an exercise in mind-expansion. If you’re willing to invest some time in learning about static types’ advantages, disadvantages, and use cases, it could help your programming immensely.
事实证明,学习类型不仅仅是拓展思维能力的一种练习。 如果您愿意花一些时间来学习静态类型的优点,缺点和用例,则可以极大地帮助您的编程。
Interested? Well you’re in luck — that’s what the rest of this four-part series is about.
有兴趣吗 好吧,您很幸运–这就是这个由四个部分组成的系列文章的其余部分。
一,定义 (First, a definition)
The quickest way to understand static types is to contrast them with dynamic types. A language with static types is referred to as a statically-typed language. On the other hand, a language with dynamic types is referred to as a dynamically-typed language.
理解静态类型的最快方法是将它们与动态类型进行对比。 具有静态类型的语言称为静态类型语言 。 另一方面,具有动态类型的语言称为动态类型的语言。
The core difference is that statically-typed languages perform type checking at compile time, while dynamically-typed languages perform type checking at runtime.
核心区别在于, 静态类型的语言在编译时执行类型检查,而动态类型的语言在运行时执行类型检查。
This leaves one more concept for you to tackle: what does “type-checking” mean?
剩下的一个概念供您解决:“ 类型检查”是什么意思?
To explain, let’s look at types in Java versus Javascript.
为了说明,让我们看一下Java与Javascript中的类型。
“Types” refers to the type of data being defined.
“类型”是指要定义的数据的类型。
For example, in Java if you define a boolean
as:boolean result = true;
例如,在Java中,如果将boolean
定义为: boolean result = true;
This has a correct type, because the boolean
annotation matches the value given to result
, as opposed to an integer or anything else.
这具有正确的类型,因为boolean
注释与给result
给出的值匹配,而不是整数或其他任何值。
On the other hand, if you tried to declare:boolean result = 123;
另一方面,如果您尝试声明: boolean result = 123;
…this would fail to compile because it has an incorrect type. It explicitly marks result
as a boolean
, but then defines it as the integer 123
.
…由于类型错误,因此无法编译。 它显式将result
标记为boolean
,然后将其定义为整数123
。
JavaScript and other dynamically-typed languages have a different approach, allowing the context to establish what type of data is being defined:
JavaScript和其他动态类型化语言具有不同的方法,允许上下文确定要定义的数据类型:
var result = true;
var result = true;
Long story short: statically-typed languages require you to declare the data types of your constructs before you can use them. Dynamically-typed languages do not. JavaScript implies the data type, while Java states it outright.
长话短说:静态类型的语言要求您先声明构造的数据类型,然后才能使用它们。 动态类型的语言则没有。 JavaScript隐含了数据类型,而Java则将其完全声明。
So as you can see, types allow you to specify program invariants, or the logical assertions and conditions under which the program will execute.
如您所见,类型使您可以指定程序不变式或程序将在其下执行的逻辑断言和条件。
Type-checking verifies and enforces that the type of a construct (constant, boolean, number, variable, array, object) matches an invariant that you’ve specified. You might, for example, specify that “this function always returns a string.” When the program runs, you can safely assume that it will return a string.
类型检查验证并强制执行构造的类型(常量,布尔值,数字,变量,数组,对象)与您指定的不变量匹配。 例如,您可以指定“此函数始终返回字符串”。 程序运行时,可以放心地假设它将返回一个字符串。
The differences between static type checking and dynamic type checking matter most when a type error occurs. In a statically-typed language, type errors occur during the compilation step, that is, at compile time. In dynamically-typed languages, the errors occur only once the program is executed. That is, at runtime.
发生类型错误时,静态类型检查和动态类型检查之间的差异最为重要。 在静态类型的语言中,在编译步骤期间(即在编译时)会发生类型错误。 在动态类型的语言中,仅在执行程序后才发生错误。 也就是说,在运行时 。
This means that a program written in a dynamically-typed language (like JavaScript or Python) can compile even if it contains type errors that would otherwise prevent the script from running properly.
这意味着以动态类型语言(例如JavaScript或Python)编写的程序可以编译,即使该程序包含类型错误也可能导致脚本无法正常运行。
On the other hand, if a program written in a statically-typed language (like Scala or C++) contains type errors, it will fail to compile until the errors have been fixed.
另一方面,如果以静态类型的语言(例如Scala或C ++)编写的程序包含类型错误,则在修复错误之前,它将无法编译。
JavaScript的新时代 (A new era of JavaScript)
Because JavaScript is a dynamically-typed language, you can go about declaring variables, functions, objects and anything without declaring the type.
因为JavaScript是一种动态类型的语言,所以您可以声明变量,函数,对象和其他任何东西而无需声明类型。
Convenient, but not always ideal. Which is why tools like Flow and TypeScript have recently stepped in to give JavaScript developers the *option* to use static types.
方便,但并不总是理想的。 这就是为什么诸如Flow和TypeScript之类的工具最近介入以使JavaScript开发人员可以选择使用静态类型的原因。
Flow is an open-source static type checking library developed and released by Facebook that allows you to incrementally add types to your JavaScript code.
Flow是Facebook开发和发行的开源静态类型检查库,它允许您将类型逐步添加到JavaScript代码中。
TypeScript, on the other hand, is a superset that compiles down to JavaScript — although it feels almost like a new statically-typed language in its own right. That said, it looks and feels very similar to JavaScript and isn’t hard to pick up.
另一方面, TypeScript是可编译为JavaScript的超集,尽管它本身感觉几乎就像是一种新的静态类型化语言。 也就是说,它的外观和感觉与JavaScript非常相似,并且不难掌握。
In either case, when you want to use types, you explicitly tell the tool about which file(s) to type-check. For TypeScript you do this by writing files with the .ts
extension instead of .js
. For Flow, you include a comment on top of the file with @flow
在任何一种情况下,当您要使用类型时,都可以明确告知工具要检查哪些文件。 对于TypeScript,您可以通过编写扩展名为.ts
而不是.js
文件来实现。 对于Flow,使用@flow
在文件顶部添加@flow
Once you’ve declared that you want to type-check a file, you get to use their respective syntax for defining types. One distinction to make between the two tools is that Flow is a type “checker” and not a compiler. TypeScript, on the other hand, is a compiler.
声明要对文件进行类型检查后,就可以使用它们各自的语法来定义类型。 两种工具之间的区别是Flow是类型“检查器”而不是编译器。 另一方面,TypeScript是编译器。
I truly believe that tools like Flow and TypeScript present a generational shift and advancement for JavaScript.
我真的相信,诸如Flow和TypeScript之类的工具将为JavaScript带来代代相传的进步 。
Personally, I’ve learned so much by using types in my day-to-day. Which is why I hope you’ll join me on this short and sweet journey into static types.
就个人而言,我通过每天使用类型学到了很多东西。 这就是为什么我希望您能和我一起经历短暂而愉快的静态类型之旅。
The rest of this 4-part post will cover:
此4部分帖子的其余部分将涉及:
Part I. A quick intro to the Flow syntax and language
第一部分: Flow语法和语言快速入门
Parts II & III. Advantages & Disadvantages of static types (with detailed walk-through examples)
第二部分和第三部分。 静态类型的优缺点(详细的演练示例)
Part IV. Should you use static types in JavaScript or not?
第四部分 您是否应该在JavaScript中使用静态类型?
Note that I chose Flow over TypeScript in the examples in this post because of my familiarity with it. For your own purposes, please do research and pick the right tool for you. TypeScript is also fantastic.
请注意,由于对本文的熟悉,我在本文的示例中选择了Flow over TypeScript。 为了您自己的目的,请进行研究并选择适合您的工具。 TypeScript也很棒。
Without further ado, let’s begin!
事不宜迟,让我们开始吧!
第1部分:Flow语法和语言快速入门 (Part 1: A quick intro to Flow syntax and language)
To understand the advantages and disadvantages of static types, you should first get a basic understanding of the syntax for static types using Flow. If you’ve never worked in a statically-typed language before, the syntax might take a little while to get used to.
要了解静态类型的优缺点,首先应该使用Flow基本了解静态类型的语法。 如果您以前从未使用过静态类型的语言,则语法可能需要一些时间才能习惯。
Let’s begin by exploring how to add types to JavaScript primitives, as well as constructs like Arrays, Object, Functions, and etc.
让我们开始探讨如何向JavaScript原语以及类型(如数组,对象,函数等)添加类型。
布尔值 (boolean)
This describes a boolean
(true or false) value in JavaScript.
这描述了JavaScript中的boolean
(正确或错误)。
Notice that when you want to specify a type, the syntax you use is:
请注意,当您要指定类型时,使用的语法是:
数 (number)
This describes an IEEE 754 floating point number. Unlike many other programming languages, JavaScript doesn’t define different types of numbers (like integers, short, long, and floating points). Instead, numbers are always stored as double precision floating point numbers. Hence, you only need one number type to define any number.
这描述了IEEE 754浮点数。 与许多其他编程语言不同,JavaScript不会定义不同类型的数字(例如整数,短整数,长整数和浮点数)。 而是始终将数字存储为双精度浮点数。 因此,您只需要一种数字类型即可定义任何数字。
number
includes Infinity
and NaN
.
number
包括Infinity
和NaN
。
串 (string)
This describes a string.
这描述了一个字符串。
空值 (null)
This describes the null
data type in JavaScript.
这描述了JavaScript中的null
数据类型。
虚空 (void)
This describes the undefined
data type in JavaScript.
这描述了JavaScript中undefined
数据类型。
Note that null
and undefined
are treated differently. If you tried to do:
请注意,对null
和undefined
的处理方式有所不同。 如果您尝试这样做:
Flow would throw an error because the type void
is supposed to be of type undefined
which is not the same as the type null
.
Flow将引发错误,因为void
类型应该是undefined
类型,与null
类型不同。
数组 (Array)
Describes a JavaScript array. You use the syntax Array<
;T> to describe an array whose elements are of some
type T.
描述一个JavaScript数组。 您使用语法Array<
; T>来描述一个数组,其元素是
类型T。
Notice how I replaced T
with string
, which means I’m declaring messages
as an array of strings.
请注意,我是如何用string
替换T
,这意味着我将messages
声明为字符串数组。
目的 (Object)
This describes a JavaScript object. There are a few different ways to add types to objects.
这描述了一个JavaScript对象。 有几种不同的方法可以向对象添加类型。
You could add types to describe the shape of an object:
您可以添加类型来描述对象的形状:
You could define objects as maps where you map a string to some value:
您可以将对象定义为将字符串映射到某个值的映射:
You could also define an object as an Object
type:
您还可以将对象定义为Object
类型:
This last approach lets us set any key and value on your object without restriction, so it doesn’t really add much value as far as type-checking is concerned.
这最后一种方法使我们可以不受限制地在您的对象上设置任何键和值,因此就类型检查而言,它实际上并没有增加太多的值。
任何 (any)
This can represent literally any type. The any
type is effectively unchecked, so you should try to avoid using it unless absolutely necessary (like when you need to opt out of type checking or need an escape hatch).
这实际上可以表示任何类型。 any
类型实际上是未经检查的,因此除非绝对必要,否则您应尝试避免使用它(例如,当您需要选择退出类型检查或需要进行转义填充时)。
One situation you might find any
useful for is when using an external library that extends another system’s prototypes (like Object.prototype).
你可能会发现一个情况any
使用扩展另一个系统的原型(比如Object.prototype中)的外部库时有用的。
For example, if you are using a library that extends Object.prototype with a doSomething
property:
例如,如果您使用通过doSomething
属性扩展Object.prototype的库:
You may get an error:
您可能会得到一个错误:
To circumvent this, you can use any
:
为了避免这种情况,您可以使用以下any
:
功能 (Functions)
The most common way to add types to functions is to add types to it’s input arguments and (when relevant) the return value:
向函数添加类型的最常见方法是向其输入参数和返回值(在相关时)添加类型:
You can even add types to async functions (see below) and generators:
您甚至可以将类型添加到异步函数(参见下文)和生成器中:
Notice how our second parameter getPurchaseLimit
is annotated as a function that returns a Promise
. And amountExceedsPurchaseLimit
is annotated as also returning a Promise
.
请注意,第二个参数getPurchaseLimit
如何被注释为返回Promise
的函数。 并且amountExceedsPurchaseLimit
被注释为还返回Promise
。
输入别名 (Type alias)
Type aliasing is one of my favorite ways to use static types. They allow you to use existing types (number, string, etc.) to compose new types:
类型别名是我最喜欢的使用静态类型的方法之一。 它们允许您使用现有类型(数字,字符串等)来编写新类型:
Above, I created a new type called PaymentMethod
which has properties that are comprised of number
and string
types.
上面,我创建了一个名为PaymentMethod
的新类型,它具有由number
和string
类型组成的属性。
Now if you want to use the PaymentMethod
type, you can do:
现在,如果要使用PaymentMethod
类型,则可以执行以下操作:
You can also create type aliases for any primitive by wrapping the underlying type inside another type. For example, if you want to type alias a Name
and EmailAddress
:
您还可以通过将基础类型包装在另一个类型中来为任何基元创建类型别名。 例如,如果您要输入别名Name
和EmailAddress
:
By doing this, you’re indicating that Name
and Email
are distinct things, not just strings. Since a name and email aren’t really interchangeable, doing this prevents you from accidentally mixing them up.
通过这样做,您表示“ Name
和“ Email
是不同的东西,而不仅仅是字符串。 由于名称和电子邮件实际上并不能互换,因此可以防止您不小心混淆它们。
泛型 (Generics)
Generics are a way to abstract over the types themselves. What does this mean?
泛型是一种抽象类型本身的方法。 这是什么意思?
Let’s take a look:
让我们来看看:
I created an abstraction for the type T
. Now you can use whatever type you want to represent T
. For numberT
, T
was of type number
. Meanwhile, for arrayT
, T was of type Array<numb
er>.
我为类型T
创建了一个抽象。 现在,您可以使用任何想要表示T
类型。 对于numberT
, T
为number
类型。 同时,对于arrayT
,T的类型为Array<numb
arrayT
>。
Yes, I know. It’s dizzying stuff if this is the first time you’re looking at types. I promise the “gentle” intro is almost over!
是的我知道。 如果这是您第一次查看类型,那真是令人头晕的东西。 我保证“温柔”的介绍已经结束!
也许 (Maybe)
Maybe type allows us to type annotate a potentially null
or undefined
value. They have the type T|void|null
for some type T
, meaning it is either type T
or it is undefined
or null
. To define a maybe
type, you put a question mark in front of the type definition:
也许type允许我们键入可能为null
或undefined
值的注释。 对于某些类型T
,它们具有类型T|void|null
,这意味着它是类型T
或undefined
或为null
。 要定义一个maybe
类型,可以在类型定义的前面加一个问号:
Here I’m saying that message is either a string
, or it’s null
or undefined
.
在这里,我说的是消息是string
,或者为null
或undefined
。
You can also use maybe to indicate that an object property will be either of some type T
or undefined
:
您还可以使用也许表明对象属性将是T
类型或undefined
类型:
By putting the ?
next to the property name for middleInitial
, you can indicate that this field is optional.
通过放置?
在middleInitial
的属性名称middleInitial
,可以指示该字段是可选的。
不相交的工会 (Disjoint unions)
This is another powerful way to model data. Disjoint unions are useful when you have a program that needs to deal with different kinds of data all at once. In other words, the shape of the data can be different based on the situation.
这是另一种强大的数据建模方法。 当您有一个需要同时处理各种数据的程序时,不相干联合很有用。 换句话说,数据的形状可以根据情况而不同。
Extending on the PaymentMethod
type from our earlier generics example, let’s say that you have an app where users can have one of three types of payment methods. In this case, you can do something like:
PaymentMethod
我们从前面的通用示例扩展了PaymentMethod
类型,那么您有一个应用程序,用户可以在其中使用三种付款方式之一。 在这种情况下,您可以执行以下操作:
Then you can define your PaymentMethod type as a disjoint union with three cases.
然后,您可以将您的PaymentMethod类型定义为三种情况的不相交联合。
Payment method now can only ever be one of these three shapes. The property type
is the property that makes the union type “disjoint”.
现在,付款方式只能是这三种形状之一。 属性type
是使联合类型“不相交”的属性。
You’ll see more practical examples of disjoint union types later in part II.
在第二部分的后面,您将看到不连续联合类型的更多实际示例。
All right, almost done. There are a couple other features of Flow worth mentioning before concluding this intro:
好吧,快完成了。 在结束本简介之前,还需要提及Flow的其他几个功能:
1) Type inference: Flow uses type inference where possible. Type inference kicks in when the type checker can automatically deduce the data type of an expression. This helps avoid excessive annotation.
1)类型推断 :流尽可能使用类型推断。 当类型检查器可以自动推断表达式的数据类型时,类型推断就开始了。 这有助于避免过多的注释。
For example, you can write:
例如,您可以编写:
Even though this Class doesn’t have types, Flow can adequately type check it:
即使此类没有类型,Flow也可以进行适当的类型检查:
Here I’ve tried to define area
as a string
, but in the Rectangle
class definition we defined width
and height
as numbers. So based on the function definition for area
, it must be return a number
. Even though I didn’t explicitly define types for the area
function, Flow caught the error.
在这里,我尝试将area
定义为string
,但是在Rectangle
类定义中,我们将width
和height
定义为数字。 因此,根据area
的功能定义,必须返回一个number
。 即使我没有为area
函数明确定义类型,Flow仍然捕获了错误。
One thing to note is that the Flow maintainers recommend that if you were exporting this class definition, you’d want to add explicit type definitions to make it easier to find the cause of errors when the class is not used in a local context.
需要注意的一件事是,Flow维护人员建议,如果您正在导出此类定义,则希望添加显式类型定义,以使当不在本地上下文中使用该类时更容易找到错误原因。
2) Dynamic type tests: What this basically means is that Flow has logic to determine what the the type of a value will be at runtime and so is able to use that knowledge when performing static analysis. They become useful in situations like when Flow throws an error but you need to convince flow that what you’re doing is right.
2)动态类型测试 :这基本上意味着Flow具有逻辑来确定运行时值的类型,因此能够在执行静态分析时使用该知识。 它们在诸如Flow抛出错误但您需要使Flow确信所做的事情是正确的情况下很有用。
I won’t go into too much detail because it’s more of an advanced feature that I hope to write about separately, but if you want to learn more, it’s worth reading through the docs.
我不会赘述太多,因为它是我希望单独编写的一项高级功能,但是如果您想了解更多信息,则值得阅读这些文档 。
我们已经完成了语法 (We’re done with syntax)
We covered a lot of ground in one section! I hope this high-level overview has been helpful and manageable. If you’re curious to go deeper, I encourage you to dive into the well-written docs and explore.
我们在一个部分中介绍了很多内容! 我希望此概述对您有所帮助且易于管理。 如果您想进一步了解,建议您深入研究编写良好的文档并进行探索。
With syntax out of the way, let’s finally get to the fun part: exploring the advantages and disadvantages of using types!
不用担心语法,让我们最后进入有趣的部分: 探索使用类型的优缺点 !
Next up: Part 2 & 3.
接下来: 第2和3部分 。
翻译自: https://www.freecodecamp.org/news/why-use-static-types-in-javascript-part-1-8382da1e0adb/
相关文章:

客户端如何连接 DataSnap Server 调用服务的方法
一般http访问的地址是 http://localhost:8099/datasnap/rest/TServerMethods1/EchoString/abc 一、用FDConnection1连接Datasnap服务器 FireDAC 连接Datasnap服务端。这个是tcp协议连接通讯,长连接。服务端不是没个方法都建立实例释放实例,而是连接的时…

Solr_全文检索引擎系统
Solr介绍: Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务。Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。 Solr的作用: solr是一个现成的全文检索引擎系统, 放入tomcat下可以…

swift 数组 filter reduce sort 等方法
数组的常用方法 swift 数组有很多的操作方法,但是用的时候用常常想不起来,就列出来看看 map 和 flatMap对数组中的元素进行变形操作filter主要对数组进行过滤reduce主要对数组进行计算sort对数组进行排序forEach循环遍历每一个元素min 和 max找出数组中…

im和音视频开发哪个更好_找时间成为更好的开发人员
im和音视频开发哪个更好There’s no time for anything. At least that’s how it feels doesn’t it? No time to learn all the things you think you need to learn to stay ahead of the curve. No time to go back and refactor that ugly piece of code. It works (sort…

4-8 同义词
雅思阅读:剑4~剑8阅读的所有同义词转换 雅思必考词汇 Cambridge 4 TEST 1 1. ignorepay no attentionnot pay any attentiontake no noticenot take any notice忽略,无视v. 2. encounterfaceconfrontmeet遇见,遭遇v. 3. mistaken viewmisconc…

swift可选类型
import UIKitvar array1 ["1","2","3","4","5"];// 1 if let 是一个组合关键字 来进行可选绑定 // 解决Optional对象解包时产生空对象的处理。 for i in array1 {print(i); }if let idx array1.firstIndex(of: "4&q…

java 配置及Eclipse安装
jdk下载 点我~ Java SE Development Kit 8u20 You must accept the Oracle Binary Code License Agreement for Java SE to download this software. Accept License Agreement Decline License Agreement Thank you for accepting the Oracle Binary Code License Agree…

golang 命令行_如何使用Golang编写快速有趣的命令行应用程序
golang 命令行by Peter Benjamin彼得本杰明(Peter Benjamin) 如何使用Golang编写快速有趣的命令行应用程序 (How to write fast, fun command-line applications with Golang) A while back, I wrote an article about “Writing Command-Line Applications in NodeJS”.不久前…

【Pyhon 3】: 170104:优品课堂: GUI -tkinter
from tkinter import * root Tk() root.title("BMS 图书管理系统") lbl Label(root, text书名:)#(1) lbl.pack() #(2) lbl.place(45.50) #(3) web 早期布局,, 常见。 lbl.grid(row0, column0) # web 早期布局,, 常见…

swift Sequence 和 SubSequence
1 序列 Sequence 序列协议是集合类型结构中的基础。 一个序列是代表有一系列具有相同类型的值,并且对这些值进行迭代。 协议中主要有两个参数,一个是元素Element,一个就是迭代器Iterator /// A type representing the sequences elements.…

PDF数据提取------1.介绍
1.关于PDF文件 PDF(Portable Document Format的简称,意为“便携式文件格式”)是由Adobe Systems在1993年用于文件交换所发展出的文件格式。它的优点在于跨平台、能保留文件原有格式(Layout)、开放标准,能自…

javascript_治愈JavaScript疲劳的研究计划
javascriptby Sacha Greif由Sacha Greif 治愈JavaScript疲劳的研究计划 (A Study Plan To Cure JavaScript Fatigue) Like everybody else, I recently came across Jose Aguinaga’s post “How it feels to learn JavaScript in 2016”.像其他所有人一样,我最近遇…

SQL Server中SELECT会真的阻塞SELECT吗?
在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.TEST WHERE OBJECT_ID 1 这个查询语句,其申请、释放的锁资源的过程如下所示: 而且从最常见…

appium IOS真机测试
看了 http://blog.csdn.net/today520/article/details/36378805 的文章,终于在真机上面测试成功。 由于没有开发者账号,不能发布应用到机器上面。所以就用了网易新闻的客户端来测试 没有开发者账号,貌似不能真正的开始测试。只能启动一下客户…

siwft 写时复制 Copy-On-Write
写时复制 Copy-On-Write 1 定义 在siwft 标准库中,Array,Dictionary,Set这样的集合类型是通过写时复制来实现的。 import Foundationvar a1 [1,2,3]; var a2 a1;// 将a1 复制给 a2,地址打印结果是相同的// 0x1--0x2--0x3 pri…

超越技术分析_超越技术面试
超越技术分析by Jaime J. Rios由Jaime J. Rios 超越技术面试 (Transcending the Technical Interview) “Wow. What a chastening and shameful experience that was.”“哇。 那真是一种令人st目结舌的经历。” This was my immediate mental reaction after I completed my…

轻松获取LAMP,LNMP环境编译参数配置
轻松获取LAMP,LNMP环境编译参数配置 作者:Mr.Xiong /分类:系统管理 字号:L M S大家是否遇到过去了新公司,公司内的LAMP,LNMP等所有的环境都是配置好的(已经在提供服务了),公司又没有留下部署文档…

java内存分配--引用
栈内存 对象地址 堆内存 存放属性 public class TestDemo{ public static void main(String args[]){ Person perA new Person(); //出现new百分之百就是要申请堆内存 perA.name"王强"; //perA 地址存放在栈内存中,同一块内存只能存…

iOS NSObject对象内存大小
NSObject内存大小 类的本质是结构体 无须赘述 struct NSObject { Class isa; };一个类对象的实例大小是8个字节 之所以打印出的16个字节,是因为一个NSObject 最小开辟16个字节 NSObject *obj [[NSObject alloc]init];// class_getInstanceSize 这是runtime 获…

客户端渲染 服务端渲染_这就是赢得客户端渲染的原因
客户端渲染 服务端渲染A decade ago, nearly everyone was rendering their web applications on the server using technologies like ASP.NET, Ruby on Rails, Java, and PHP.十年前,几乎每个人都使用ASP.NET,Ruby on Rails,Java和PHP等技术…

java多线程三之线程协作与通信实例
多线程的难点主要就是多线程通信协作这一块了,前面笔记二中提到了常见的同步方法,这里主要是进行实例学习了,今天总结了一下3个实例: 1、银行存款与提款多线程实现,使用Lock锁和条件Condition。 附加 :…

Java8中Lambda表达式的10个例子
Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 Java代码 //Before Java 8: new Thread(new Runnable() { Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); …
OC的对象的分类
OC的对象分类 一 oc的对象分类主要分为3种 1 instance 对象: 实例对象就是通过alloc 出来的对象,一个类每一次的alloc都会产生一个新的实例对象 StudentA *a [[StudentA alloc]init];StudentA *b [[StudentA alloc]init];// 打印结果如下 地址是明显…

如何在国内上medium_在Medium上写作的风格指南
如何在国内上mediumAfter spending more than 1,000 hours writing and editing stories for our Medium publication, I’ve decided to create this living style guide for contributors. Feel free to use it for your publication as well.在花了1000多个小时为我们的《中…

C# webform上传图片并生成缩略图
其实里面写的很乱,包括修改文件名什么的都没有仔细去写,主要是想记录下缩略图生成的几种方式 ,大家明白就好! 1 void UpImgs()2 {3 if (FileUpload1.HasFile)4 {5 string fileContentType FileUpload1.Pos…

ios中的自动释放池
自动释放池中是否有虑重功能 1 autoreleasepool { 2 UIView *view [UIView alloc] init] autorelease]; 3 [view autorelease]; 4 } 这样写在自动释放池的队列中是两个对象还是一个对象,就是说把view加到自动释放池的队列时,队列本身是…

arch linux安装_如何从头开始安装Arch Linux
arch linux安装by Andrea Giammarchi由Andrea Giammarchi In this article, youll learn how to install Arch Linux from scratch… and in about 5 minutes. So lets get to it.在本文中,您将学习如何从头开始安装Arch Linux,大约需要5分钟。 因此&am…

CoreCRM 开发实录 —— Profile
再简单的功能,也需要一坨代码的支持。Profile 的编辑功能主要就是修改个人的信息。比如用户名、头像、性别、电话……虽然只是一个编辑界面,但添加下来,涉及了6个文件的修改和7个新创建的文件。各种生成的和手写的代码,共有934行之…

iOS KVO 的实现原理
KVO 的实现原理 一 原理 1.KVO是基于runtime机制实现的 2.当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter 方法。派生类在被重写的setter方法内实现真正的通知机制 …
利用UltimateAndroid框架进行快速开发
UltimateAndroid是一套集成了许多现有优秀的Android开源类库并将之组合成一个整体的Android快速开发框架。框架目前主要包含的功能有View Injection,ORM,异步网络请求和图片加载,自动化脚本测试,磁盘LRU等功能.同时提供了类似于TripleDes、Webview快速设置、Md5处理…