TS学习笔记四:函数及泛型枚举

news/2024/2/23 16:00:24/文章来源:https://blog.csdn.net/m0_37631110/article/details/135640823

  本节介绍ts的函数及泛型的相关内容,包括函数的声明格式及泛型的相关知识。

  1. 视频讲解

    TS学习笔记四:函数的定义使用

  2. B站视频

    TS学习笔记四:函数的定义使用

  3. 西瓜视频
    https://www.ixigua.com/7321535978286514727
    在这里插入图片描述

一、函数

  函数是js程序的基础,可以实现抽象层/模拟类/信息隐藏和模块,ts中已经支持类/命名空间和模块,但函数是主要定义行为的地方,ts为js函数添加了额外的功能。

1.函数

  可以创建带有名字的函数或匿名函数,实例如下:

function add(x, y) {return x + y;
}
let myAdd = function(x, y) { return x + y; };

函数可以使用函数体外部的变量,如:

let z = 100;
function addToZ(x, y) {return x + y + z;
}

2.函数类型

  可以给每个参数添加类型之后再为函数本身添加返回值类型,ts能够根据返回语句自动推断出返回值类型,示例如下:

function add(x: number, y: number): number {return x + y;
}
let myAdd = function(x: number, y: number): number { return x+y; };

  函数的完整类型定义如下:

let myAdd: (x:number, y:number)=>number = function(x: number, y: number): number { return x+y; };

  函数类型包含两部分:参数类型和返回值类型,使用参数列表的形式写出参数类型,为每个参数指定名字和类型,只要参数类型是匹配的就可以,参数名不一定一致。返回值部分的类型使用=>符号声明,返回值类型是函数类型的必要部分,若没有任何返回值,则可指定为void,但是不能留空。

3.推断类型

  赋值语句的时候一边指定了类型但是另一边没有类型的话,ts编译器会自动识别出类型,叫做按上下文归类,是类型推论的一种:

// myAdd has the full function type
let myAdd = function(x: number, y: number): number { return x + y; };// The parameters `x` and `y` have the type number
let myAdd: (baseValue:number, increment:number) => number =function(x, y) { return x + y; };

4.可选参数和默认参数

  ts中每个函数参数都是必须的,编译器会检查用户是否为每个参数都传入了值,还会假设只有这些参数会被传递进函数,即传递给一个函数的参数个数必须与函数期望的参数个数一致。

function buildName(firstName: string, lastName: string) {return firstName + " " + lastName;
}
let result1 = buildName("Bob");                  // 报错,缺少参数
let result2 = buildName("Bob", "Adams", "Sr.");  //报错,多了参数
let result3 = buildName("Bob", "Adams");         // ah, just right

  js函数中的每个参数都是可选的,可传可不传,没传参数的时候,它的值就是undefined,在ts中可以在参数名旁边使用?实现可选参数的功能,如:

function buildName(firstName: string, lastName?: string) {if (lastName)return firstName + " " + lastName;elsereturn firstName;
}
let result1 = buildName("Bob");  // works correctly now
let result2 = buildName("Bob", "Adams", "Sr.");  // 错误,多了参数
let result3 = buildName("Bob", "Adams");  // ah, just right

  可选参数必须跟在必须参数后面,否则会报错。也可以为参数提供一个默认值,即当用户没有传递参数或者传递的值是undefined时,就自动获取默认值作为参数的值,示例如下:

function buildName(firstName: string, lastName = "Smith") {return firstName + " " + lastName;
}
let result1 = buildName("Bob");                  // works correctly now, returns "Bob Smith"
let result2 = buildName("Bob", undefined);       // still works, also returns "Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr.");  // 异常,多个参数
let result4 = buildName("Bob", "Adams");         // ah, just right

  在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略,即可选参数与末尾的默认参数共享参数类型。

function buildName(firstName: string, lastName?: string) {// ...
}
function buildName(firstName: string, lastName = "Smith") {// ...
}

  带默认值的参数不需要放在必须参数的后面,如果带默认值的参数出现在必须参数的前面,用户必须明确的传入undefined值来获取默认值,如:

function buildName(firstName = "Will", lastName: string) {return firstName + " " + lastName;
}
let result1 = buildName("Bob");                  //异常,少参数
let result2 = buildName("Bob", "Adams", "Sr.");  // 异常,多了参数
let result3 = buildName("Bob", "Adams");         // okay and returns "Bob Adams"
let result4 = buildName(undefined, "Adams");     // okay and returns "Will Adams"

5.剩余参数

  必要参数/默认参数和可选参数都表示某一个参数,若不知道有多少个参数传递的时候,可以使用arguments来访问所有传入的参数。ts中可以将所有参数收集到一个变量里:

function buildName(firstName: string, ...restOfName: string[]) {return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

  剩余参数会被当作个数不限的可选参数,可以一个都没有,也可以有任意多个,会创建参数数组,使用…指定,…后面给的的名字即时参数数组的名称,使用方式如下:

function buildName(firstName: string, ...restOfName: string[]) {return firstName + " " + restOfName.join(" ");
}
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;

6.this和箭头函数

  js中this的值在函数被调用的时候才会指定,示例如下:

let deck = {suits: ["hearts", "spades", "clubs", "diamonds"],cards: Array(52),createCardPicker: function() {return function() {let pickedCard = Math.floor(Math.random() * 52);let pickedSuit = Math.floor(pickedCard / 13);return {suit: this.suits[pickedSuit], card: pickedCard % 13};}}
}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);

  上述示例代码会报错,因为createCardPicker函数返回的函数里的this被设置成了window而不是deck对象,因为独立调用了cardPicker,此时调用会将this视为window,严格模式下this为undefined而不是window。
  若要正确的使用,可以在函数返回的时候就绑好正确的this,可以使用箭头函数,箭头函数会保存函数创建时的this值,而不是调用时的值,示例如下:

let deck = {suits: ["hearts", "spades", "clubs", "diamonds"],cards: Array(52),createCardPicker: function() {// NOTE: the line below is now an arrow function, allowing us to capture 'this' right herereturn () => {let pickedCard = Math.floor(Math.random() * 52);let pickedSuit = Math.floor(pickedCard / 13);return {suit: this.suits[pickedSuit], card: pickedCard % 13};}}
}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);

  上述代码中如果给编译器设置了–noImplicitThis标记。 它会指出this.suits[pickedSuit]里的this的类型为any。若需要明确具体的类型,可以提供一个显示的this参数,如下:

function f(this: void) {// make sure `this` is unusable in this standalone function
}
interface Card {suit: string;card: number;
}
interface Deck {suits: string[];cards: number[];createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {suits: ["hearts", "spades", "clubs", "diamonds"],cards: Array(52),// NOTE: The function now explicitly specifies that its callee must be of type DeckcreateCardPicker: function(this: Deck) {return () => {let pickedCard = Math.floor(Math.random() * 52);let pickedSuit = Math.floor(pickedCard / 13);return {suit: this.suits[pickedSuit], card: pickedCard % 13};}}
}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);

  上述示例中Deck 接口的createCardPicker指定了this的类型,则调用时候this的类型就是Deck的,而不是any,此时–noImplicitThis就不会报错了。
  有时候在回调函数中this也会报错,因为当函数被当作参数传递,并作为回调函数时,当回调被调用的时候,会被当作一个普通函数调用,this将为undefined,可以通过this参数来避免错误,如下:

interface UIElement {addClickListener(onclick: (this: void, e: Event) => void): void;
}

  this: void表示addClickListener期望onclick是一个不需要this类型的函数。

class Handler {info: string;onClickBad(this: Handler, e: Event) {// oops, used this here. using this callback would crash at runtimethis.info = e.message;};
}
let h = new Handler();
uiElement.addClickListener(h.onClickBad); // error!

  指定了this类型后,因为显示的声明了onClickBad必须在Handler的实例上调用,ts会检测到addClickListener要求函数带有this: void,可以改变this类型修复此错误:

class Handler {info: string;onClickGood(this: void, e: Event) {// can't use this here because it's of type void!console.log('clicked!');}
}
let h = new Handler();
uiElement.addClickListener(h.onClickGood);

  因为onClickGood指定了this类型为void,因此传递addClickListener是合法的,但不能使用this.info,若都需要,则可以使用箭头函数了:

class Handler {info: string;onClickGood = (e: Event) => { this.info = e.message }
}

  因为箭头函数不会捕获this,所以可以进行传递,但每个Handler对象都会创建一个箭头函数,方法指挥被创建一次,添加到Handler的原型链上,在不同的Handler对象间是共享的。

7.重载

  js中函数传入不同的参数可返回不同类型的数据,如下:

let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x): any {// Check to see if we're working with an object/array// if so, they gave us the deck and we'll pick the cardif (typeof x == "object") {let pickedCard = Math.floor(Math.random() * x.length);return pickedCard;}// Otherwise just let them pick the cardelse if (typeof x == "number") {let pickedSuit = Math.floor(x / 13);return { suit: suits[pickedSuit], card: x % 13 };}
}
let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

  pickCard方法根据传入参数的不同会返回两种不同的类型,可以对函数提供多个函数类型定义来进行函数重载,编译器会根据这个列表去处理函数的调用,示例如下:

let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {// Check to see if we're working with an object/array// if so, they gave us the deck and we'll pick the cardif (typeof x == "object") {let pickedCard = Math.floor(Math.random() * x.length);return pickedCard;}// Otherwise just let them pick the cardelse if (typeof x == "number") {let pickedSuit = Math.floor(x / 13);return { suit: suits[pickedSuit], card: x % 13 };}
}
let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

  重载的pickCard函数在调用的时候会进行正确的类型检查,处理时会查找重载列表,尝试使用第一个重载定义,如果匹配则使用,因此使用的时候最好把精确的定义放在最前面,示例中function pickCard(x): any并不是重载列表的一部分,因此示例中只有两个重载,一个是接受对象另一个是接受数字,其他的参数将会产生错误。

二、泛型

  工程使用过程中,需要考虑可重用性,不仅能够支持当前的数据类型,也可以支持未来的数据类型。可以使用泛型来创建可重用的组件,让一个组件可支持多种类型的数据,示例如下:

function identity<T>(arg: T): T {return arg;
}
&emsp;&emsp;也可以使用any来定义函数,如:
function identity(arg: any): any {return arg;
}

  虽然使用any后函数能接受任何类型的参数,但是却丢失了一部分信息,即传入的类型和传出的类型应该是相同的,但是实际不确定具体的类型,使用了泛型后就能确保传入的参数和传出的值类型是一致的。泛型不会丢失信息,定义了泛型函数之后,有两种调用方式:
第一种,可传入所有的参数,包含类型参数,明确的指定了T是string类型,并作为参数传给函数,使用<>进行处理,如下:

let output = identity<string>("myString");  // type of output will be 'string'

第二种,可使用类型推导,让编译器自动根据传递的参数类型确定具体的类型,此时没必须要使用<>来明确的传入类型,如下:

let output = identity("myString");  // type of output will be 'string'

1.泛型变量

  使用泛型创建泛型函数时,编译器要求函数体必须正确的使用,必须把参数当作任意或所有类型,示例如下:

function identity<T>(arg: T): T {return arg;
}

  如果想获取arg的长度,调用arg.length,编译器将会报错,因为没有地方指明arg具有length属性,此处的变量代表的时任意类型。也可以传入泛型指定的数组,如下:

function loggingIdentity<T>(arg: T[]): T[] {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}

  也可以使用如下方式定义:

function loggingIdentity<T>(arg: Array<T>): Array<T> {console.log(arg.length);  // Array has a .length, so no more errorreturn arg;
}

2.泛型接口

  可使用V和W作为类型变量来表示任何字母都可以,名称没有具体的含义,JS中不支持泛型,所以在编译后无泛型相关的代码,泛型纯粹是为了编译时进行类型的校验,确保类型的安全抽象。使用方式:

interface Identities<V, W> {id1: V,id2: W
}

3.泛型类

  泛型类与泛型接口类型,使用<>指定泛型类型,跟在类名后面。使用如下:

class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

  与接口一样,直接把泛型类型放到类的后面,可以帮助确认类的所有属性都在使用相同的类型。
注意:泛型指定的是类的实例部分,所有类的静态部分不能使用泛型类型。

4.泛型约束

  上述例子中使用参数arg的length属性时因为参数的类型时任意类型,所以会报错,这时可以使用泛型约束确保参数都包含length属性,这样既可以在函数中访问length属性了。示例如下:

interface Lengthwise {length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length);  // Now we know it has a .length property, so no more errorreturn arg;
}

  此时泛型函数被定义了约束,因此它不再是可以使用任意类型:

loggingIdentity(3);  // Error, number doesn't have a .length property

  需要传入符合约束类型的值,必须包含需要的属性才可以:

loggingIdentity({length: 10, value: 3});

  可以声明一个类型参数,且它被另一个类型参数所约束,比如:

function find<T, U extends Findable<T>>(n: T, s: U) {// ...
}
find (giraffe, myAnimals);

  在 TypeScript 使用泛型创建工厂函数时,需要引用构造函数的类类型,比如:

function create<T>(c: {new(): T; }): T {return new c();
}

三、枚举

  使用枚举可以定义有名字的数字常量,通过enum关键字进行定义:

enum Direction {Up = 1,Down,Left,Right
}

1.枚举

  一个枚举类型可以包含零个或多个枚举成员,枚举成员具有一个数字值,可以是常数或计算得出的值,常数时需要满足一下条件:

  • 不具有初始化函数并且之前的枚举成员是常数,此时当前枚举成员的值为上一个枚举成员的值加1,第一个枚举元素的初始值是0。
  • 枚举成员使用常数枚举表达式初始化,常数枚举表达式是ts表达式的子集,可以在编译阶段求值,当满足以下条件时,就是一个常数枚举表达式:
    • 数字字面量
    • 引用之前定义的常数枚举成员,可以在不同的枚举类型中定义,如果成员是在同一个枚举类型中定义的,可以使用非限定名来引用
    • 带括号的常数枚举表达式
    • +, -, ~ 一元运算符应用于常数枚举表达式
    • +, -, *, /, %, <<, >>, >>>, &, |, ^ 二元运算符,常数枚举表达式做为其一个操作对象 若常数枚举表达式求值后为 NaN或Infinity,则会在编译阶段报错。
      其它所有情况的枚举成员被当作是需要计算得出的值:
enum FileAccess {// constant membersNone,Read    = 1 << 1,Write   = 1 << 2,ReadWrite  = Read | Write// computed memberG = "123".length
}

  枚举是在运行时真正存在的一个对象,可以从枚举值到枚举名进行反向映射,如下:

enum Enum {A
}
let a = Enum.A;
let nameOfA = Enum[Enum.A]; // "A"

  编译后,枚举类型被编译成一个对象,它包含双向映射(name->value)和(value->name)。引用枚举成员总会生成一次属性访问并且永远不会内联,当访问枚举值时为了避免生成多余的代码和间接引用,可以使用常数枚举,常数枚举使用const修饰符。

const enum Enum {A = 1,B = A * 2
}

  常数枚举只能使用常数枚举表达式并且不同于常规的枚举是它们在编译阶段会被删除,常数枚举成员在使用的地方被内联进来,是因为常数枚举不可能有计算成员。

const enum Directions {Up,Down,Left,Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]

  编译后代码为:

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];

2.外部枚举

  外部枚举用于描述已经存在的枚举类型的形状。

declare enum Enum {A = 1,B,C = 2
}

  外部枚举和非外部枚举之间有一个重要的区别,正常的枚举中,没有初始化方法的成员被当作常数成员,对于非常数的外部枚举而言,没有初始化方法时被当作需要经过计算的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_925890.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[oeasy]python005_退出游乐场_重启游乐场_系统态shell_应用态_quit

0005_ 退出游乐场_重启游乐场_系统态shell 退出终端_重启游乐场_shell_quit &#x1f94a; Python 回忆 上次 了解了 python进入了 python 游乐场 在游乐场 可以做 简单的计算还可以做 乘方运算 数字特别大之后 游乐场 会迟疑一下不过 最终 还是能算出来 可以让数字 更大一…

Vue学习笔记3--全局事件总线

Vue学习笔记3—全局事件总线 1.全局事件总线可以实现任意组件间通信 X需具备的条件&#xff1a; 所有的组件都要能看见X可以调用$on $off $emitVue.prototype.x {a:1, b:2} 可以被所有组件看见VueComponent.protoype.proto Vue.prototype组件实例对象(vc)可以访问到Vue原型上…

Java多线程并发篇----第十八篇

系列文章目录 文章目录 系列文章目录前言一、寄存器二、程序计数器三、PCB-“切换桢”四、上下文切换的活动五、引起线程上下文切换的原因前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了…

QT软件在线安装与维护

一.安装 安装QT开发环境分离线安装和在线安装两种方式&#xff0c;具体步骤如下&#xff1a; QT官网注册账号----下载安装包-----安装-----选择要安装的版本与开发包----版本维护 注意&#xff1a;Qt5.14.2是最后提供二进制安装包的版本&#xff0c;后面的版本都需要在线安装…

小程序系列--7.页面配置以及网络数据请求

一. 页面配置 1.页面配置文件的作用 小程序中&#xff0c;每个页面都有自己的 .json 配置文件&#xff0c;用来对当前页面的窗口外观、页面效果等进行配置。 2. 页面配置和全局配置的关系 3. 页面配置中常用的配置项 二、网络数据请求 1. 小程序中网络数据请求的限制 2. 配…

数据分析中常用的指标或方法

一、方差与标准差二、协方差三、皮尔逊系数四、斯皮尔曼系数 一、方差与标准差 总体方差 V a r ( x ) σ 2 ∑ i 1 n ( x i − x ˉ ) 2 n ∑ i 1 n x i 2 − n x ˉ 2 n E ( x 2 ) − [ E ( x ) ] 2 Var(x)\sigma^2\frac {\sum\limits_{i1}^{n} (x_i - \bar{x})^2} {n…

SQL性能分析手段

SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供整个服务器执行sql的状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff1a; -- session 是查看当前会话 ; -- globa…

数据结构排序二叉树(下)

哎,调了几天深度学习模型,今天来更新排序二叉树 文章目录 前言 一、排序二叉树的结构定义 二、在排序二叉树添加数据 三、定义创建排序二叉树函数 四、查找一棵二叉排序树中的结点x的所在层数 五、删除二叉排序树中T关键字x的节点 六、查找二叉排序树中的所有小于key的关…

【小笔记】算法训练基础超参数调优思路

【学而不思则罔&#xff0c;思维不学则怠】 本文总结一下常见的一些算法训练超参数调优思路&#xff08;陆续总结更新&#xff09;&#xff0c;包括&#xff1a; batchsize学习率epochsdropout&#xff08;待添加&#xff09; Batch_size 2023.9.29 简单来说&#xff0c;较…

Kotlin程序设计(二)面向对象

Kotlin程序设计中级篇 我们在前面已经学习了Kotlin程序设计的基础篇&#xff0c;本章我们将继续介绍更多Kotlin特性&#xff0c;以及面向对象编程。 函数 其实函数我们在一开始就在使用了&#xff1a; fun main() {println("Hello World") }我们程序的入口点就是…

day3:基于UDP模型的简单文件下载

思维导图 tftp文件下载客户端实现 #include <head.h> #define SER_PORT 69 #define SER_IP "192.168.125.223" int link_file() {int sfdsocket(AF_INET,SOCK_DGRAM,0);if(sfd-1){perror("socket error");return -1;}return sfd; } int filedownloa…

【Spring Cloud Alibaba】Sentinel 服务熔断与流量控制

目录 前言 一、Sentinel 入门 1.1 什么是 Sentinel ? 1.2 微服务集成 Sentinel 1.3 安装Sentinel控制台 二、Jmeter 压力测试工具 2.1 Jmeter 介绍 2.2 Jmeter 安装 2.3 接口测试 三、Sentinel 使用 3.1 限流规则 3.1.1 warm up(预热模式) 3.1.2 排队等待 3.1.3…

mathtype2024版本下载与安装(mac版本也包含在内)

安装包补丁主要是mathtype的安装包&#xff0c;与它的补丁。 详细安装过程&#xff1a; step1&#xff1a; 使用方法是下载完成后先安装MathType-win-zh.exe文件&#xff0c;跟着步骤走直接安装就行。 step2&#xff1a; 关闭之后&#xff0c;以管理员身份运行MathType7PJ.exe…

【数据结构和算法】反转链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;迭代&#xff08;双指针&#xff09; 2.2 方法二&#xff1a;递归 三、代码 3.…

survey和surveyCV:如何用R语言进行复杂抽样设计、权重计算和10折交叉验证?

一、引言 在实际调查和研究中&#xff0c;我们往往面临着样本选择的复杂性。复杂抽样设计能够更好地反映真实情况&#xff0c;提高数据的代表性和可靠性。例如&#xff0c;多阶段抽样可以有效地解决大规模调查的问题&#xff0c;整群抽样能够在保证样本的随机性的同时减少资源消…

网络安全全栈培训笔记(53-WEB攻防-通用漏洞跨域CORS资源JSONP回调域名接管劫持)

第54天 WEB攻防-通用漏洞&跨域CORS资源&JSONP回调&域名接管劫持 知识点&#xff1a; 1、子域名接管检测&探针&利用 2、C0SP跨域资源检测&探针&利用 3、JSONP跨域回调-检侧&探针&利用 #前置知识点&#xff1a; 同源策路(SOP),“同源”包…

centos7配置时间同步网络时间

centos7配置时间同步网络时间 1、安装 NTP 工具。 sudo yum install -y ntp2启动 NTP 服务。 sudo systemctl start ntpd3、将 NTP 服务设置为开机自启动。 sudo systemctl enable ntpd4、验证 date

【特征工程】分类变量:MultiLabelBinarizer对多标签数据进行编码

MultiLabelBinarizer 说明介绍 1. MultiLabelBinarizer 是什么&#xff1f; MultiLabelBinarizer是scikit-learn库中的一个用于处理多标签数据的编码器。通常用于将多标签的分类任务中的标签转化为二进制形式&#xff0c;便于机器学习模型的处理。该编码器的主要目标是将每个…

【网络安全】【密码学】【北京航空航天大学】实验一、数论基础(上)【C语言和Java实现】

实验一、数论基础&#xff08;上&#xff09; 一、实验目的 1、通过本次实验&#xff0c;熟悉相关的编程环境&#xff0c;为后续的实验做好铺垫&#xff1b; 2、回顾数论学科中的重要基本算法&#xff0c;并加深对其的理解&#xff0c;为本学期密码学理论及实验课程打下良好…

《ARM Linux内核源码剖析》读书笔记——0号进程(init_task)的创建时机

最近在读《ARM Linux内核源码剖析》&#xff0c;一直没有看到0号进程&#xff08;init_task进程)在哪里创建的。直到看到下面这篇文章才发现书中漏掉了set_task_stack_end_magic(&init_task)这行代码。 下面这篇文章提到&#xff1a;start_kernel()上来就会运行 set_task_…