当前位置: 首页 > 编程日记 > 正文

javascript优缺点_为什么要在JavaScript中使用静态类型? 优缺点

javascript优缺点

by Preethi Kasireddy

通过Preethi Kasireddy

为什么要在JavaScript中使用静态类型? 优缺点 (Why use static types in JavaScript? The Advantages and Disadvantages)

We covered a lot of ground in Part 1! With syntax out of the way, let’s finally get to the fun part: exploring the advantages and disadvantages of using static types.

在第1部分中,我们讨论了很多内容! 不用担心语法,让我们最后进入有趣的部分:探索使用静态类型的优缺点。

使用静态类型的优点 (The Advantages of using static types)

Static types offer many benefits when writing programs. Let’s explore a few of them.

静态类型在编写程序时提供许多好处。 让我们探索其中的一些。

优势1:您可以及早发现错误和错误 (Advantage 1: You can detects bugs and errors early)

Static type checking allows us to verify that the invariants we specified are true without actually running the program. And if there’s any violation of those invariants, they will be discovered before runtime instead of during it.

静态类型检查使我们无需实际运行程序即可验证我们指定的不变量为真。 而且,如果违反了这些不变量,则将在运行时而不是在运行时发现它们。

A quick example: suppose we have a simple function that takes a radius and calculates the area:

一个简单的例子:假设我们有一个简单的函数,该函数采用半径并计算面积:

Now, if we were to pass a radius which is not a number (e.g. ‘im evil’)…

现在,如果我们要传递的半径不是数字(例如,“邪恶”),…

…we’d get back NaN. If some piece of functionality relied on this calculateArea function always returning a number, then this result might lead to a bug or crash. That’s not very pleasing, is it?

…我们会取回NaN 。 如果某些依赖此calculateArea函数的功能始终返回一个数字,则此结果可能会导致错误或崩溃。 那不是很好吗?

Had we used static types, we could have specified the exact input(s) and output types for the function:

如果我们使用静态类型,则可以为该函数指定确切的输入和输出类型:

Try to pass anything but a number into our calculateArea function now, and Flow will send us a handy-dandy message:

现在尝试将数字以外的任何内容传递到我们的calculateArea函数中,Flow会向我们发送方便的消息:

Now we’re guaranteed that the function will only ever accept valid numbers as inputs and return a valid number as output.

现在我们保证该函数将只接受有效数字作为输入,并返回有效数字作为输出。

Because the type checker tells you when there are errors while you’re coding, it’s a lot more convenient (and a lot less expensive) than finding out about the bug once the code has been shipped to your customers.

因为类型检查器会在编写代码时告诉您何时有错误,所以与将代码交付给客户后发现错误相比,它更方便(并且成本更低)。

优势2:您可以获得生活证明文件 (Advantage 2: You get living documentation)

Types serve as living, breathing documentation for both ourselves and other users of our code.

类型本身就是我们自己和我们代码的其他用户的生活,呼吸的文档。

To see how, let’s look at this method that I once found in a large code base that I was working in:

为了了解如何操作,让我们看一下我曾经在工作的大型代码库中找到的这种方法:

At first glance (and the second and third), I had no idea how to use this function.

乍一看(第二和第三),我不知道如何使用此功能。

Is quote a number? Or a boolean? Is payment method an object? Or maybe it’s a string representing the type of payment method? Does the function return the date as a string? Or as a Date object?

number吗? 还是boolean ? 付款方式是object吗? 还是它是表示付款方式类型的string ? 函数是否以string返回日期? 还是作为Date对象?

No clue.

没有线索。

My solution at the time was to evaluate the business logic and grep through the codebase until I figured it out But that’s a lot of work just to understand how a simple function works.

当时我的解决方案是评估代码中的业务逻辑和grep,直到我弄清楚为止。但是,要了解简单函数的工作原理,这需要做很多工作。

On the other hand, if we had written something like:

另一方面,如果我们写过类似的东西:

It becomes immediately clear what type of data the function takes as input and what type of data it returns as output. This demonstrates how we can use static types to communicate the intent of the function. We can tell other developers what we expect from them, and can see what they expect from us. Next time someone goes to use this function, there will be no questions asked.

可以立即清楚地知道该函数将哪种类型的数据作为输入,以及将哪种类型的数据作为输出返回。 这说明了我们如何使用静态类型来传达函数的意图 。 我们可以告诉其他开发人员我们对他们的期望,并可以看到他们对我们的期望。 下次有人使用该功能时,将不会有任何问题。

There’s an argument to be made that adding code comments or documentation could solve the same problem:

有一个论点是,添加代码注释或文档可以解决相同的问题:

This works. But it’s way more verbose. Beyond verbosity, code comments like this are difficult to maintain because they’re unreliable and lack structure — some developers might write good comments, some might write obscure comments, and some might forget to write them at all.

这可行。 但这更冗长。 除了冗长之外,像这样的代码注释还难以维护,因为它们不可靠且缺乏结构-一些开发人员可能会编写良好的注释,有些可能编写晦涩的注释,而有些则可能根本忘记编写它们。

It’s especially easy to forget to update them when you refactor. Type annotations, however, have a defined syntax and structure and can never go out of date — they’re encoded into the code.

重构时,忘记更新它们特别容易。 但是,类型注释具有已定义的语法和结构,并且永远不会过时-它们已编码为代码。

优点3:减少了复杂的错误处理 (Advantage 3: It reduces convoluted error handling)

Types help remove convoluted error handling. Let’s revisit our calculateArea function to see how.

类型有助于消除复杂的错误处理。 让我们重新看看我们的calculateArea函数,看看如何。

This time, I’ll have it take an array of radii and calculate the area for each radius:

这次,我将使用半径数组并计算每个半径的面积:

This function works, but doesn’t properly handle invalid input arguments. If we wanted to make sure that we properly handle cases where the input is not a valid array of numbers, we’d end up with a function that looks like:

此函数有效,但不能正确处理无效的输入参数。 如果我们想确保我们能够正确处理输入不是有效数字数组的情况,那么我们将得到一个看起来像这样的函数:

Wow. That’s a lot of code for a little bit of functionality.

哇。 大量功能所需的大量代码。

But with static types, we could simply do:

但是对于静态类型,我们可以简单地执行以下操作:

Now the function actually looks like what it originally looked like without all the visual clutter from error handling.

现在,该函数实际上看起来像它原来的样子,而没有来自错误处理的所有视觉混乱。

Easy enough to see the benefit, right? :)

很容易看到好处,对吗? :)

优势4:您可以更有信心地进行重构 (Advantage 4: You can refactor with greater confidence)

I’ll explain this one through an anecdote: I was working in a very large codebase once and there was a method defined on the User class that we needed to update — specially, we needed to change one of the function parameters from a string to an object.

我将通过一个轶事对此进行解释:我曾经在一个非常大的代码库中工作,并且在User类上定义了一个需要更新的方法-特别是,我们需要将一个函数参数从string更改为一个object

I made the change, but was having cold feet to commit the change — there were so many invocations of this function sprinkled around the code base that I had no idea if I’d updated all the instances properly. What if I missed some invocation deep in some untested helpers file?

我进行了更改,但是提交更改时措手不及-遍历代码库的函数调用太多,我不知道是否正确更新了所有实例。 如果我错过了一些未经测试的帮助程序文件中的某个调用,该怎么办?

The only way to know was to ship the code and pray that it didn’t blow up with errors.

唯一知道的方法是发送代码并祈祷它不会因错误而崩溃。

Using static types would have avoided this. It would have given me the assurance and peace of mind that if I updated a function and in turn, updated the type definitions, the type checker would be there for me to catch all the errors I missed. All I’d have to do is go through those type errors and fix them.

使用静态类型可以避免这种情况。 如果我更新了一个函数,然后又更新了类型定义,那将使我放心而放心,如果我更新了类型定义,则类型检查器将在那里捕获我错过的所有错误。 我要做的就是检查这些类型错误并修复它们。

优势5:它将数据与行为分开 (Advantage 5: It separates data from behavior)

One less talked-about benefit of static types is that they help separate data from behavior.

静态类型的一个鲜为人知的好处是它们有助于将数据与行为分开。

Let’s revisit our calculateAreas function with static types:

让我们重新使用静态类型的calculateAreas函数:

Think about how we’d go about composing this function. Because we’re annotating types, we are forced to first think about the type of data we intend to use so that we can appropriately define the input and output types.

考虑一下我们将如何组成此函数。 因为我们在注释类型,所以我们被迫首先考虑要使用的数据类型,以便我们可以适当地定义输入和输出类型。

Only then do we implement the logic:

只有这样我们才能实现逻辑:

This ability to precisely express the data separate from the behavior allows us to be explicit about our assumptions and more accurately convey our intent, which relieves some mental burden and brings some mental clarity to the programmer. Without it, we are left to track this mentally in some fashion.

这种精确地将数据与行为分开表达的能力使我们能够明确假设,并更准确地传达我们的意图,这减轻了一些精神负担,并为程序员带来了一些头脑清晰的感觉。 没有它,我们将以某种方式在心理上进行追踪。

优点6:消除了整个类别的错误 (Advantage 6: It eliminates an entire category of bugs)

One of the most common errors or bugs we encounter as JavaScript developers are type errors at runtime.

我们在JavaScript开发人员中遇到的最常见的错误或错误之一是运行时的类型错误。

For instance, let’s say our initial application state is defined as:

例如,假设我们的初始应用程序状态定义为:

And let’s assume that we then make an API call to fetch the messages in order to populate our appState. Next, our app has an overly simplified view component that takes in the messages (defined in our state) as a prop and displays the unread count and each message as a list item:

并假设我们随后进行API调用以获取消息,以填充appState 。 接下来,我们的应用程序具有一个过于简化的视图组件,该组件以messages (在我们的状态中定义)为支撑,并显示未读计数和每条消息为列表项:

If the API call to fetch the messages fails or returns undefined, we’d end up with a type error in production:

如果获取消息的API调用失败或返回undefined ,那么我们将在生产中遇到类型错误:

TypeError: Cannot read property ‘length’ of undefined

TypeError: Cannot read property 'length' of undefined

… and your program crashes. You lose a customer. Bummer.

…,程序崩溃。 你失去了客户。 笨蛋

Let’s see how types can help us. We’ll start by adding Flow types to our application state. I’ll type alias the AppState and then use that to define the state:

让我们看看类型如何为我们提供帮助。 首先,将Flow类型添加到应用程序状态。 我将输入AppState别名,然后使用它来定义状态:

Since our API to fetch messages is known to be unreliable, here we’re saying that messages is a maybe type of an array of strings.

由于我们已知的获取消息的API是不可靠的,因此在这里我们说messages是字符串数组的一种maybe类型。

Same deal as last time — we fetch our messages from the unreliable API and use it in our view component:

与上次相同—我们从不可靠的API获取消息,并在我们的视图组件中使用它:

Except now, Flow would catch our error and complain:

除了现在,Flow会发现我们的错误并抱怨:

Whoa buddy!

哇,哥们!

Because we defined messages as a maybe type, we are saying that it is allowed to be null or undefined. But it still does not allow us to perform operations on it (like .length or .map) without doing a null check because if the messages value was in fact null or undefined, we’d end up with a type error if we perform any operation on it.

因为我们将messages定义为maybe类型,所以我们说它可以为nullundefined 。 但是它仍然不允许我们对它执行操作(如.length.map )而不进行null检查,因为如果messages值实际上为nullundefined ,那么如果执行任何操作都会导致类型错误操作就可以了。

So let’s go back and update our view function to be something like:

因此,让我们返回并将视图功能更新为:

Flow now knows that we’ve handled the case where messages is null or undefined, and so the code type checks with 0 errors. Long dead runtime type errors :)

Flow现在知道我们已经处理了message为nullundefined ,因此代码类型检查错误为0。 长时间无效的运行时类型错误:)

优点7:减少了单元测试的次数 (Advantage 7: It reduces the number of unit tests)

We saw earlier how static types can help eliminate convoluted error handling because they guarantee input and output types. As a result, they also reduce the # of unit tests.

前面我们已经看到静态类型如何帮助消除复杂的错误处理,因为它们可以保证输入和输出类型。 结果,它们还减少了单元测试的数量。

For instance, let’s go back to our dynamically-typed calculateAreas function with error handling:

例如,让我们回到带有错误处理的动态类型的calculateAreas函数:

If we were diligent programmers, we might have thought to test invalid inputs to make sure they are handled correctly in our program:

如果我们是勤奋的程序员,我们可能会考虑测试无效的输入,以确保它们在程序中得到正确的处理:

… and so on. Except it’s very likely that we forget to test some edge cases — then our customer is the one to discover the problem. :(

… 等等。 除了极有可能我们忘记测试某些极端情况之外,我们的客户才是发现问题的人。 :(

Since tests are solely based on the cases we think to test, they are existential and easy to circumvent.

由于测试仅基于我们认为要测试的案例,因此它们是存在的且易于规避。

On the other hand, when we’re required to define types:

另一方面,当我们需要定义类型时:

…not only are we guaranteed that our intent matches reality, but they are also simply harder to escape. Unlike empirically-based tests, types are universal and difficult to be wishy-washy around.

……不仅可以保证我们的意图与现实相符,而且它们也更难逃脱。 与基于经验的测试不同,类型是通用的,很难被随意修饰。

The big picture here is: tests are great at testing logic, and types at testing data types. When combined, the sum of the parts is greater than the whole.

这里的大图是:测试擅长于测试逻辑,类型擅长于测试数据类型。 组合时,各部分的总和大于整体。

优势8:它提供了领域建模工具 (Advantage 8: It provides a domain modeling tool)

One of my favorite use cases for types is domain modeling. A domain model is a conceptual model of a domain that includes both the data and behavior on that data. The best way to understand how you can use types to do domain modeling is by looking at an example.

我最喜欢的类型用例之一是域建模。 域模型是域的概念模型,其中既包含数据又包含该数据的行为。 了解如何使用类型进行域建模的最佳方法是看一个示例。

Let’s say I have an application where a user has one or more payment methods to make purchases on the platform. There are three types of payment methods they’re allowed to have (Paypal, Credit card, Bank Account).

假设我有一个应用程序,其中用户使用一种或多种付款方式在平台上进行购买。 允许使用三种付款方式(Paypal,信用卡,银行帐户)。

So we’ll first type alias these three different payment method types:

因此,我们将首先为这三种不同的付款方式类型输入别名:

Now we can define our PaymentMethod type as a disjoint union with three cases:

现在,我们可以将PaymentMethod类型定义为以下三种情况的不相交联合:

Next, let’s model our app state. To keep it simple, let’s assume that our app data only consists of the user’s payment methods.

接下来,让我们为应用程序状态建模。 为简单起见,假设我们的应用程序数据仅由用户的付款方式组成。

Is this good enough? Well, we know that to get the user’s payment methods, we need to make an API request, and depending on where in the fetching process we are, our app will have different states. So there’s actually four possible states:

这样够好吗? 好吧,我们知道要获取用户的付款方式,我们需要发出一个API请求,并且根据我们在获取过程中的位置,我们的应用程序将具有不同的状态。 因此,实际上有四种可能的状态:

1) We haven’t fetched the payment methods2) We are fetching the payment methods3) We successfully fetched the payment methods4) We tried fetching but there was an error fetching the payment methods

1)我们尚未获取付款方式2)我们正在获取付款方式3)我们成功获取了付款方式4)我们尝试获取但获取错误的付款方式

But our simple Model type with paymentMethods doesn’t cover all these cases. Instead, it assumes that paymentMethods always exists.

但是我们带有paymentMethods简单Model类型无法涵盖所有​​这些情况。 相反,它假定paymentMethods始终存在。

Hmmm. Is there a way to model our app state to be one of these four cases, and only these four cases? Let’s take a look:

嗯 有没有一种方法可以将我们的应用程序状态建模为这四种情况之一,并且只有这四种情况? 让我们来看看:

We used a disjoint union type to define our state as one of the four scenarios described above. Notice how I am using a type property to determine which of the four states our app is in. This type property is actually what makes this a disjoint union. Using this, we can do case analysis to determine when we have the payment methods and when we don’t.

我们使用脱节联合类型将状态定义为上述四种情况之一。 请注意,我是如何使用type属性确定应用程序处于四个状态中的哪个状态的。此type属性实际上是使它成为不相交联合的原因。 使用此方法,我们可以进行案例分析,以确定何时使用付款方式以及何时不使用付款方式。

You’ll also notice that I pass in a generic type E and D into the app state. Type D will represent the user’s payment method (PaymentMethod defined above). We haven’t defined type E, which will be our error type, so let’s do that now:

您还会注意到,我将通用类型ED传递到应用程序状态。 类型D将代表用户的付款方式( PaymentMethod定义的PaymentMethod )。 我们尚未定义类型E ,这将是我们的错误类型,所以让我们现在开始:

Now, we can model our app domain as:

现在,我们可以将应用程序域建模为:

In summary, the signature for our app state is now AppState<E, D> — where E is of the shape HttpError and D is PaymentMethod. And AppState has four (and only these four) possible states: NotFetched, Fetching, Failure and Success.

总之,我们的应用程序状态的签名是现在AppState<E, d> - w这里E是的shape Htt佩罗rD is Payment方式. And Ap . And Ap pState有四个(只有这四个)可能的状态ates: NotF et ates: NotF ched, Fe hing, F失败e and S成功。

I find this type of domain modeling useful for thinking about and building user interfaces against certain business rules. The business rules tells us that our app can only ever be in one of these states. So this allows us to explicitly represent build our app state and guarantees that it will only ever be in one of the pre-defined states. And when we build off of this model (e.g. to create a view component), it comes blatantly obvious that we need to handle all four possible states.

我发现这种类型的域建模对于思考和构建针对某些业务规则的用户界面很有用。 业务规则告诉我们,我们的应用程序只能处于以下状态之一。 因此,这使我们可以明确表示构建应用程序状态,并保证它永远不会处于预定义状态之一。 当我们建立这个模型(例如创建一个视图组件)时,很明显我们需要处理所有四种可能的状态。

Moreover, the code become self-documenting — you can look at the union cases and immediately figure out how the app state is structured.

而且,代码变成了自我记录的文件-您可以查看并用例并立即弄清楚应用程序状态的结构。

使用静态类型的缺点 (The Disadvantages of using static types)

Like anything else in life and programming, static type checking comes with its tradeoffs.

就像生活和编程中的其他任何事情一样,静态类型检查也会带来一些折衷。

It’s important that we understand and acknowledge them so we can make an informed decision of when static types make sense and when they simply aren’t worth it.

重要的是我们要理解并认可它们,以便我们能够明智地决定何时应该使用静态类型,以及何时根本不应该使用它们。

Here are a few of those considerations:

以下是一些注意事项:

劣势1:静态类型需要预先投资才能学习 (Disadvantage 1: Static types require investment upfront to learn)

One reason JavaScript is such a fantastic language for beginners is because it doesn’t require the student to learn an entire type system before they can be productive in the language.

JavaScript对初学者来说是一种很棒的语言的一个原因是,它不需要学生在学习该语言之前就能学习整个类型系统。

When I initially learned Elm (a statically-typed functional language), the types often got in the way. I would constantly run into compiler errors related to my type definitions.

当我最初学习Elm(一种静态类型的功能语言)时,通常会遇到这种类型的问题。 我会经常遇到与我的类型定义有关的编译器错误。

Learning how to use the type system effectively has been half the battle in learning the language itself. As a result, static types made the learning curve for Elm steeper than for JavaScript.

学习如何有效使用类型系统已成为学习语言本身的一半。 结果,静态类型使Elm的学习曲线比JavaScript陡峭。

This matters especially for beginners where the cognitive load of learning syntax is at an all time high. Adding types to the mix can overwhelm a beginner.

这对于学习语法的认知负荷一直很高的初学者尤其重要。 在混音中添加类型可能会使新手不知所措。

劣势2:粗俗会使你陷入困境 (Disadvantage 2: Verbosity can bog you down)

Static types often make programs look more verbose and cluttered.

静态类型通常使程序看起来更冗长和混乱。

For example, instead of:

例如,代替:

We’d have to write:

我们必须写:

And instead of:

而不是:

We’d have to write:

我们必须写:

Obviously, this can add extra lines of code. But there are a couple arguments against this being a real downside.

显然,这会增加额外的代码行。 但是,有很多人反对这是一个真正的弊端。

Firstly, as we mentioned earlier, static types help eliminate an entire category of tests. Some developers would consider this a perfectly reasonable tradeoff.

首先,正如我们前面提到的,静态类型有助于消除整个测试类别。 一些开发人员会认为这是一个完全合理的权衡。

Secondly, as we saw earlier, static types can sometimes eliminate the convoluted error handling and in turn reduce the visual clutter of code significantly.

其次,正如我们前面所看到的,静态类型有时可以消除复杂的错误处理,进而显着减少代码的视觉混乱。

It’s hard to say whether verbosity is a real argument against types, but it’s one worth keeping in mind.

很难说冗长性是否是针对类型的真正论点,但值得牢记。

劣势3:类型需要时间来掌握 (Disadvantage 3: Types take time to master)

It takes time and lots of practice to learn how best to specify types in a program. Moreover, developing a good sense for what is worth tracking statically and what to keep dynamic also requires careful thought, practice, and experience.

学习如何最好地指定程序类型需要花费时间和大量练习。 此外,要对应该静态跟踪的内容和要保持动态的内容建立良好的感觉,还需要仔细的思考,实践和经验。

For example, one approach we might take is to encode critical business logic with types, while leaving short-lived or unimportant pieces of logic dynamic to avoid needless complexity.

例如,我们可能采用的一种方法是使用类型对关键业务逻辑进行编码,同时保留短暂或不重要的逻辑动态以避免不必要的复杂性。

This distinction can be tough to make, especially when developers less experienced with types are making judgment calls on the fly.

这种区分可能很难做到,尤其是当对类型缺乏经验的开发人员在进行动态判断时。

劣势4:静态类型会阻碍快速发展 (Disadvantage 4: Static types can hold up rapid development)

As I mentioned earlier, types tripped me up a bit when I was learning Elm — particularly when adding code or making changes. Constantly being distracted by compiler errors made it difficult to feel like I was making any progress.

正如我前面提到的,当我学习Elm时,类型使我有些不适,尤其是在添加代码或进行更改时。 不断地因编译器错误而分散注意力,这使我很难感到自己正在取得任何进展。

The argument here is that static type checking might cause a programmer to lose focus too often — and as we know, focus is key for writing good programs.

这里的论点是,静态类型检查可能会导致程序员过于频繁地失去焦点-并且我们知道,焦点是编写好的程序的关键。

Not only that, but static type checkers aren’t always perfect. Sometimes you run into situations where you know what you need to do and the type checking just gets in the way.

不仅如此,静态类型检查器并不总是完美的。 有时,您会遇到一些情况,您知道自己需要做什么,而类型检查就成为了障碍。

I’m sure there are other tradeoffs I’m missing, but these were the big ones for me.

我确定还有其他折衷方案,但这些对我来说是很大的。

接下来, 最后的结论 (Up next, the final conclusion)

In the final section, we’ll conclude by discussing whether it makes sense to use static types.

在最后一节中 ,我们将讨论使用静态类型是否有意义。

I’ll see you there.

我在那儿见。

翻译自: https://www.freecodecamp.org/news/why-use-static-types-in-javascript-part-2-part-3-be699ee7be60/

javascript优缺点

相关文章:

大数的减法函数--c语言

代码展示&#xff1a; http://paste.ubuntu.com/23693598/ #include<stdio.h> #include<stdlib.h> #include<string.h> char * largeDiffer(char *a,char *b){ /* 使用说明 传入的a和b只能为整数 结果为a-b;返回的为字符指针&#xff0c;注意数组不要越…

json 基础

json格式 JSON格式&#xff1a;http://www.json.org/ python和JSON的关系请参考&#xff1a;http://docs.python.org/library/json.html JSON建构有两种结构&#xff1a; 1. “名称/值”对的集合&#xff08;A collection of name/value pairs&#xff09;。不同的语言中&#…

iOS 中 load 和 initialize的实现顺序

1 load 函数 调用时机&#xff0c;当类引用进项目的时候执行load函数&#xff0c;在main函数开始之前&#xff0c;与 这个类是否被用到是无关的&#xff0c;每个类的load函数都会自动调用一次。 1 父类和子类都实现load函数的时候&#xff0c;父类的load方法优先于子类 2 类…

需求简报_代码简报:有史以来最怪诞的丑毛衣

需求简报Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事&#xff1a; The geekiest ugly sweater ever: 4 minute read 有史以来最怪异的丑毛衣&#xff1a; 4分钟阅读 Lessons from my post-bootcamp job …

C#内置函数 RunSql的使用

作用批量执行sql语句表达式.RunSQL(SQLStatement,UseTransaction)表达式.一个代表DoCmd对象的变量。注释&#xff1a;sqlstatement参数的最大长度为 32,768 个字符&#xff08;而"宏"窗口中的 SQL 语句操作参数的最大长度为 256 个字符&#xff09;。 官方说仅能用于…

swif 在字符串中查找特定字符索引以及改变字符串的指定位置的颜色 字体大小

1 第一种方式 var text "谁包含这个字母";let range:Range<String.Index> text.range(of: "含")!;let end_idx:Int text.distance(from: text.startIndex, to: range.lowerBound);// 打印2print(end_idx);类方法 抽取 // 查找对应索引static func…

SD卡的控制方法(指令集和控制时序)

1.SD卡的命令格式&#xff1a; SD卡的指令由6字节(Byte)组成&#xff0c;如下&#xff1a; Byte1&#xff1a;0 1 x x x x x x(命令号&#xff0c;由指令标志定义&#xff0c;如CMD39为100111即16进制0x27&#xff0c;那么完整的CMD39第一字节为01100111&#xff0c;即0x270x40…

javascript 代码_代码简介:2016年JavaScript的现状

javascript 代码Here are three stories we published this week that are worth your time:这是我们本周发布的三个值得您关注的故事&#xff1a; The state of JavaScript in 2016: 5 minute read 2016年JavaScript状况&#xff1a; 阅读5分钟 Upgrading to macOS Sierra wi…

Unity协程截图,WWWForm、WWW配合上传

先说一下原理。。 截图有两种方法&#xff0c;第一种&#xff1a; Application.CaptureScreenshot(url); 这个API可以截全屏并保存到指定路径 这里我们不采用此方法 下面的代码采用第二种方法&#xff0c;自己建一个Texture2D 这种方法灵活&#xff0c;操作性更高 WWWForm方法是…

OC 的反射机制以及使用场景

OC 的反射机制 一 定义概念 普遍的概念就是类似于java的反射机制&#xff0c;动态机制使得OC语言更加灵活。 反射机制就是可以根据指定的类名获取类的相关信息。 二 作用 1 根据类名获得class // 选择器 和字符串之间的相互转化 FOUNDATION_EXPORT NSString *NSStringFr…

centos 网卡聚合及Cisco交换机链路聚合

一、配置环境 centos 系统。网卡1口和2口做链路聚合。 交换机网口 6口和7口。 二、服务器操作步骤 centos 6 1.创建一个channel bonding interface #vi /etc/sysconfig/network-scripts/ifcfg-bond0 添加如下几行&#xff1a; GATEWAY192.168.10.1 DNS1202.106.0.20 DEVICEb…

graphql redux_如何在Redux应用程序中使用GraphQL

graphql reduxby Howon Song通过宋颂恩 如何在Redux应用程序中使用GraphQL (How to use GraphQL in your Redux app) Fetching and managing data in Redux requires too much work. As Sashko Stubailo points out:在Redux中获取和管理数据需要太多的工作。 正如Sashko Stuba…

原创:去繁存简,回归本源:微信小程序公开课信息分析《一》

以前我开过一些帖子&#xff0c;我们内部也做过一些讨论&#xff0c;我们从张小龙的碎屏图中 &#xff0c;发现了重要讯息&#xff1a; 1&#xff1a;微信支付将成为重要场景&#xff1b; 2&#xff1a;这些应用与春节关系不小&#xff0c;很多应用在春节时&#xff0c;有重要的…

ubuntu 14.0 下github 配置

一&#xff1a;创建Repositories 1:首先在github下创建一个帐号。这个不用多说&#xff0c;然后创建一个Repositories。 2:然后在ubuntu下安装git相关的东东&#xff1a; 1sudo apt-get install git-core git-gui git-doc -y 3:在ubuntu本地创建一个ssh密匙&#xff1a; 1ssh-k…

OC 消息转发实现多继承

消息转发实现多继承 在OC 中&#xff0c;一个类只支持单继承&#xff0c;但是可以通过别的手段实现多继承。 利用消息转发实现多继承。 在OC 中&#xff0c;对象调用方法实际是在发消息&#xff0c;对象接收到一条消息的时候&#xff0c;消息函数随着对象的isa 指针到自己的…

chatscript_如何使用ChatScript构建您的第一个聊天机器人

chatscriptby Giorgio Robino通过乔治罗宾诺(Giorgio Robino) 如何使用ChatScript构建您的第一个聊天机器人 (How to build your first chatbot using ChatScript) 10–10–2018: article updated with new github repo url.2018年10月10日&#xff1a;文章更新为新的github r…

web安全浅析

就之前本人主持开发的金融产品所遇到的安全问题&#xff0c;设计部分请参见&#xff1a;http://www.cnblogs.com/shenliang123/p/3835072.html 这里就部分web安全防护就简单的交流&#xff1a; 1.1系统安全 1.1.1 客户端脚本安全 &#xff08;1&#xff09;跨站脚本攻击&#…

HDU 1556 Color the ball

题解&#xff1a;基础的树状数组区间修改&#xff0c;单点查询。 #include <cstdio> #include <cstring> int c[100005],a,b,n; int modify(int x,int num){while(x<n)c[x]num,xx&-x;} int query(int x){int s0;while(x>0)sc[x],x-x&-x;return s;} …

OC协议实现多继承

协议实现多继承 协议实现多继承的话&#xff0c;只是简答的提供了接口&#xff0c;并灭有提供实现的方式。 A #import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINprotocol StuAProtocal <NSObject>// 学生A 会游泳 - (void)swimming;endinterface Stude…

扶梯正确使用_乘坐自动扶梯解释CSS浮动

扶梯正确使用by Kevin Kononenko凯文科诺年科(Kevin Kononenko) 乘坐自动扶梯解释CSS浮动 (CSS Floats Explained By Riding An Escalator) 如果您曾经跳过自动扶梯&#xff0c;那么您可以快速了解浮动。 (If you have ever jumped on an escalator, then you can quickly und…

安卓学习-界面-ui-ListView

ListView继承自AbsListView AbsListView属性 XML属性代码说明 android:choiceMode setChoiceMode(int choiceMode) AbsListView.CHOICE_MODE_SINGLEAbsListView.CHOICE_MODE_MULTIPLEAbsListView.CHOICE_MODE_MULTIPLE_MODAL none :无选择模式 singleChoice&#xff1a;允许单…

swift 浮点型字符串的运算

// 1 两个浮点字符串之间的运算 let str1 "1.3"; let str2 "2.4"; let val1 Double(str1); let val2 Double(str2);let val3 CGFloat(Double(str1)!) * CGFloat(Double(str2)!);print(val3);// 2 string 转 double 不失精度 let formattor NumberFo…

为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)

by Preethi Kasireddy通过Preethi Kasireddy 为什么要在JavaScript中使用静态类型&#xff1f; (使用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 …

客户端如何连接 DataSnap Server 调用服务的方法

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

Solr_全文检索引擎系统

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

swift 数组 filter reduce sort 等方法

数组的常用方法 swift 数组有很多的操作方法&#xff0c;但是用的时候用常常想不起来&#xff0c;就列出来看看 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 同义词

雅思阅读&#xff1a;剑4~剑8阅读的所有同义词转换 雅思必考词汇 Cambridge 4 TEST 1 1. ignorepay no attentionnot pay any attentiontake no noticenot take any notice忽略&#xff0c;无视v. 2. encounterfaceconfrontmeet遇见&#xff0c;遭遇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…