Rust学习日记(二)变量的使用--结合--温度换算/斐波那契数列--实例
前言:
这是一个系列的学习笔记,会将笔者学习Rust语言的心得记录。
当然,这并非是流水账似的记录,而是结合实际程序项目的记录,如果你也对Rust感兴趣,那么我们可以一起交流探讨,使用Rust来构建程序。
注:本文中使用Rust都是在windows环境下,如果是macOS或者linux,其指令或有不同,请注意。
系列第一篇:Rust学习日记(一)Cargo的使用
概述:
这是Rust学习笔记的第二篇,主要说一下Rust中的变量,本文将结合两个实例来说明,这两个实例分别是:
1、在华氏度和摄氏度之间转换温度
2、生成指定个数(n)的斐波那契数列
如果你看过rust的官方手册,那你会熟悉,这两个例子事实上就是官方留的“课后习题”
在进入实例之前,还是要先来简单看看变量的使用。
变量的申明
1、关键词let
在rust中,申明变量的关键词就是let。如果你使用过其他语言,那么你可能对rust的变量申明有疑问,为什么用let?
我觉得不用纠结,这就是一个定义,使用什么单词来作为关键词并不重要,重要的是,这个关键词的作用。
fn main() {let x=5;println!("x is {x}");
}
上面的示例程序段,是在主函数中创建了变量x,并打印,在终端输入cargo run,输出如下:
PS D:\008 rustpro\var> cargo runFinished dev [unoptimized + debuginfo] target(s) in 0.02sRunning `target\debug\var.exe`
x is 5
2、变量的可变与不可变
变量,顾名思义,就是可变化的量,不可变的是变量吗?不可变的应该是常量吧?
在rust中,默认情况下,变量是不可变的。
这是rust的设计,它的目的,当然是为了安全。“安全”是贯穿rust整个体系的,后面会有更多更复杂更高级的功能,都会和它有关。
fn main() {let x=5;println!("x is {x}");x=x+1;println!("x is {x}");
}
对前面的函数稍作修改,给变量x再次赋值,再看输出:
PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)
error[E0384]: cannot assign twice to immutable variable `x`--> src\main.rs:4:5|
2 | let x=5;| -| || first assignment to `x`| help: consider making this binding mutable: `mut x`
3 | println!("x is {x}");
4 | x=x+1;| ^^^^^ cannot assign twice to immutable variableFor more information about this error, try `rustc --explain E0384`.
error: could not compile `var` (bin "var") due to previous error
错误提示,cannot assign twice to immutable variable,不能给“immutable variable”分配两次,什么叫immutable variable?就是不可变变量。
所以,现在你就知道,rust是比较奇葩的了。
但是,这就是rust的设计,如果你定义变量的时候,只是简单的let x=5;那么这个x是不可变的。那如果要可变呢:
let mut x=5;
再加一个关键词mut,mut其实就是mutable的简写,可变的。
fn main() {let mut x=5;println!("x is {x}");x=x+1;println!("x is {x}");
}
cargo run:
PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)Finished dev [unoptimized + debuginfo] target(s) in 0.43sRunning `target\debug\var.exe`
x is 5
x is 6
可以发现,“变量x”的值可以多次分配,也就是真正的可变了。
看到这里你发现什么?
你会发现,在rust里,你对一个对象,比如变量的定义,必须要十分清楚,可变就可变,不可变就不可变,
这样一来,rust编译器就能非常清楚地知道,你定义这个变量的目的,它会编译过程对你的意图全程跟踪,
不可变变量如果不小心让它变化,编译器就会报错,提示你,对你来说,这就是安全。
你不用等程序都运行了,然后偶尔崩溃了一次,然后去找bug,找来找去无论怎么编译就是没问题,但一运行就报错,这是令人崩溃的。
你已经了解到rust中变量的奇葩性了,我们接着再看几个,然后再进入实例。
3、常量
rust中常量用const来申明,这个const应该是比较熟悉的单词了,很多编程语言申明常量都是用它吧。
const也就是Constants的简写。
看一下申明的格式吧:
const C_1=5;
如果你真的这么写,cargo check一下,会报错:
PS D:\008 rustpro\var> cargo checkChecking var v0.1.0 (D:\008 rustpro\var)
error: missing type for `const` item--> src\main.rs:6:14|
6 | const C_1=5;| ^ help: provide a type for the constant: `: i32`error: could not compile `var` (bin "var") due to previous error
rust编译器提示你,需要给常量提供一个数据类型,并且给了你一个选项:i32。
rust中的数据类型----整数型:
关于数据类型,其实我认为不用多说,照着手册看看了解一下即可,因为一般来说,对编程有所了解的,对数据类型一般都不陌生,可以说,几乎所有语言中的数据类型,都大同小异。
常见的比如说整数、浮点数、布尔量、字符串等,还有一些复杂的,比如结构体(复合体)、数组、列表、元组等。
我们接着说常量,上面说这样写const C_1=5;会报错,原因是未给常量提供数据类型,所以我们应该这么来申明常量
const C_1:i32=5;
rust就是这样,它要求你明确,哪怕是常量,它不会为你隐式转换,它要求你定义常量时,明确常量的数据类型。
到此,你会发现,rust似乎很“麻烦”,这也要明确,那也要明确,为什么不能像其他语言一样,直接a=5;或者const a=5;
我只能说,rust它就是这样一门语言,如果你对此实在不能接受,那么放弃是好的,如果无所谓,那么就按照rust的规则,暂时先走下去。
4、变量的覆盖
我们在本文前面说过,rust中的变量有可变和不可变的区别,直接申明变量,默认不可变,如果要可变,需加关键词mut。
但现在我们来看另一种使用:
fn main() {let x=5;println!("x is {x}");let x:char='a';println!("x is {x}");
}
我们在第一行定义x变量,且赋值为5,但没有用mut使其可变,所以x是不可变的,但是我们在第三行再次使用x变量,而且给它赋值为字符‘a’。
我们先cargo run一下:
PS D:\008 rustpro\var> cargo runCompiling var v0.1.0 (D:\008 rustpro\var)Finished dev [unoptimized + debuginfo] target(s) in 0.63sRunning `target\debug\var.exe`
x is 5
x is a
可以看到,rust正常编译,且结果x的值被改变了。你应该看到区别,就是第三行再次使用x时,重新定义了一次。
rust中,用let来定义变量,是可以重名的,并且后一个可以覆盖前面的,所谓“shadow”,即旧的变量活在新的变量的阴影里。
你可能会觉得,这样是不是会造成困扰,如果不小心使用了一样的变量名,覆盖之前的变量数据,岂不是会影响程序。但这个问题容易解决,只需要你在命名变量时有自己的规律即可,但是rust中这样的机制会带来好处。
我们看到,同样的变量x,在第一次和第二次的定义中,不仅值可以不同,连数据类型也可以不同。
什么场景会这样使用,比如你要输入一个值,是字符类型,但程序接收字符后,要以整数型来运算,但是这两个其实一个东西,如果是其他语言,你可能会这样定义变量,x_str和x_int,但是rust中你可以只定义一个x,
let x:char='a';
let x:i32=5;
好了,关于变量就先说到这,基本上差不多了,当然这并非是说把变量的所有方面都涉及到了,只是说基本的概念都已经了解了。
下面将开始实例:
一、温度转换
1、新建一个temp项目
PS D:\008 rustpro> cargo new tempCreated binary (application) `temp` package
PS D:\008 rustpro> cd temp
PS D:\008 rustpro\temp> cargo buildCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.49s
PS D:\008 rustpro\temp>
新建项目后,rust会自动生成一个main.rs主函数。
这个主函数里默认的是打印“hello world”,我们要修改它,以达到温度转换的功能。
华氏度和摄氏度的转换关系如下:
1 摄氏度=33.8 华氏度
所以,如果我们输入一个摄氏度值为x,那么转换为华氏度应该是:f(x)=33.8*x
数学关系很清楚,是很简单的一元一次函数。
先看一下main.rs的结构:
fn main() {println!("Hello, world!");
}
fn和let一样,是关键词,定义函数,所以fn后面的main就是函数,只不过它是主函数,所以地位特殊,但是,main这个名字,想必大家也不陌生,无论是C还是python,都有主函数,地位也差不多,谁让它是main呢!
但我们先不修改main,我们先新建一个函数,就叫temp_convert:
fn temp_convert(){}
添加逻辑代码:
fn temp_convert(t:f32)->f32{let t2=t*33.8;return t2;
}
可以看到,我们在新建的函数基础上,添加了一个形式参数t,把它的数据类型定义为f32,即浮点数。
定义了一个函数返回值类型:->f32,即函数返回值也是f32类型。
然后在函数体内,定义了变量t2,其赋值为t*33.8,
最后将计算后的t2的值返回。
这个函数中形式参数t即输入的摄氏度,返回的t2即转换的华氏度。
接下来,就是在主程序里调用了:
修改一下main函数:
fn main() {let t1=temp_convert(3.0);println!("t_f is {t1}");
}
因为函数temp_convert有返回值,所以我们定义一个变量t1来储存它。
到此,简单的温度转换就实现了,只要给函数的参数赋予不同的值(摄氏度),函数就可以返回华氏度:
PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.42sRunning `target\debug\temp.exe`
t_f is 101.399994
但这样肯定不算是一个完整的程序,我们设想应该是这样,程序启动,会输出一个文字提示,让我们输入一个摄氏度,我们输入后,程序输出一个华氏度。然后能循环,这样才算是完整的转换程序。
我们分两部分来说,一是如何接受用户输入,二是如何循环。
1 用户输入
用户输入,需要用到IO接口,在rust中即std::io。
std::io,这是一个程序包crate,类似于其他程序的模块。在使用它之前,需要先导入它。
use std::io;
然后使用它:
use std::io;
fn main() {let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");
}
上面的主函数main变化较大,我们一一来说一下。我们使用use关键词导入了std::io,这是用来接受用户输入的模块。
然后在主函数体内添加程序:
let mut t_in=String::new();
这行是定义了一个可变变量t_in且类型为string。
io::stdin().read_line(&mut t_in).expect("error");
这行就是io接口的调用,用于读取用户的输入,read_line即是std::io模块的函数。&mut t_in是将我们定义的变量t_in来接受read_line的输入值。
其实上面这行直接写如下:
io::stdin().read_line(&mut t_in).expect("error");
之所以写成多行样式,是为了便于阅读。
这里的expect是对潜在错误的处理,关于错误的处理不在本文的范围,后续会有专门叙述。此处只要知道这样用就可以了。
我们现在已经从用户处接受到输入值,即t_in,接下来要对输入值进行处理:
let t_in:f32=t_in.trim().parse().expect("error");
此处我们使用前面介绍的变量覆盖,先定义了t_in为用户输入,且数据类型为string类型,接着此行用同名变量t_in定义为f32类型,覆盖之前的字符串类型。
其中的trim是消除一个字符串的开头和结尾的多余空格,parse是将字符串转为另一种数据类型,在此处就是转为f32类型。expect我们已经说过,是对返回值的判断时可能发生的错误处理。
`let t1=temp_convert(t_in);
在顺利获得用户输入的值且转为浮点类型后,我们调用写好的temp_convert转换函数,其形式参数t在调用时传入实际参数t_in。将temp_convert函数的返回值,传给变量t1。
完整程序:
use std::io;
fn main() {let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");
}
fn temp_convert(t:f32)->f32{let t2=t*33.8;return t2;
}
在终端运行cargo run:
PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.74sRunning `target\debug\temp.exe`
请输入摄氏度值:
2
华氏度是 67.6
好了,第一部分完成了,现在我们能成功根据输入的摄氏度转为华氏度且输出,但缺点是每次运行只能进行一次,所以需要循环。
循环
想让程序循环起来,也很简单,使用loop指令,它会循环执行主程序的逻辑,直到触发停止。本文中未添加明确的停止程序,因为这不在我们的学习范围,后续会有说明,此文不赘述。
fn main() {loop{let mut t_in=String::new();println!("请输入摄氏度值:");io::stdin().read_line(&mut t_in).expect("error");let t_in:f32=t_in.trim().parse().expect("error");let t1=temp_convert(t_in);println!("华氏度是 {t1}");}}
我们可以看到,只需要将main中的原程序添加进loop的{}中即可。
让我们运行一下:
PS D:\008 rustpro\temp> cargo runCompiling temp v0.1.0 (D:\008 rustpro\temp)Finished dev [unoptimized + debuginfo] target(s) in 0.46sRunning `target\debug\temp.exe`
请输入摄氏度值:
2
华氏度是 67.6
请输入摄氏度值:
3
华氏度是 101.399994
请输入摄氏度值:
4
华氏度是 135.2
请输入摄氏度值:
1
华氏度是 33.8
请输入摄氏度值:
2
华氏度是 67.6
请输入摄氏度值:
r
thread 'main' panicked at src\main.rs:10:42:
error: ParseFloatError { kind: Invalid }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\temp.exe` (exit code: 101)
可以看到,程序在不停地执行,如果用户一直输入正确的值得话,但你会发现在终端的记录中,最后输入r时,rust报错且退出了,这是因为程序中没有对非法输入的应对措施,当输入非法值时,只能报错退出。
但我不准备在本文中完善它,我相信随着我们学习rust的深入,这个问题会迎刃而解。
如果你看到这里,我相信你对rust中变量、函数的使用,有了初步的印象了。
下面我们说一下第二个实例,即实现斐波那契数列。
斐波那契数列
斐波那契数列应该是比较经典的练手题目了,你在学习其他语言如C、python、java中都可以通过编写斐波那契数列来加深对语言的理解。
rust也不例外,我在文章一开头就说过,此文所列举的两个实例,都是rust官方手册中给读者留的课后习题。
其实官方在手册的第二章给了一个很好的实例即猜谜游戏,说的非常详细,但我们作为学习者,在学习了官方手册后,自己要学会应用,所以我选择用课后习题来作为示例。
斐波那契数列是这样的数列:
1,1,2,3,5,8,13,21,34,55,89…
这个数列的规律是,从第三项开始,每一项的值都是它前面两项的和。用公式表示为:
f(n)=f(n-1)+f(n-2);n>2
所以,如果要用函数来实现斐波那契数列,函数肯定是递归的。
rust实现,首先是创建新项目,这个不用多说了。
接着创建新的函数,命名为fibonacci:
fn fibonacci(num:i32)->i32{if num<3{return 1;}else{return fibonacci(num-1)+fibonacci(num-2);}
}
这个fibonacci函数有个形式参数num,数据类型为i32,函数的返回值类型由’->'符号指出,也是i32。
函数体内的逻辑,是对num进行判断,如果num小于3,也就是fibonacci数列的前2项,那么函数返回值固定为1,如果num大于等于3,那么返回值就等于前2项之和。
此处的判断,使用了if。。else语句。if else应该不用多说了吧,这应该是学习编程的人,都会了解的。
几乎你学习任何编程语言,都会遇到if语句。
所以,本文也不会赘述if。。else语句。
接下来看main函数:
use std::io;
fn main() {loop{println!("please enter fibonacci number:");let mut number=String::new();io::stdin().read_line(&mut number).expect("err");let number:i32=number.trim().parse().expect("err");println!("number is {number}");for y in 1..number{let x=fibonacci(y);println!("fibo({y}) is {x}");}} }
可以看到,几乎和前面的实例一样,一点区别在于子函数fibonacci的调用处,这里用了for语句:
之所以使用for语句,因为斐波那契数列是一个数列,当我们给定一个斐波那契数列的项索引(n)时,我们实际上希望程序能够列出至n项的斐波那契数列所有的项。
for y in 1..number{let x=fibonacci(y);println!("fibo({y}) is {x}");}
同理,for循环也是常见的,和if语句一样,我们会在后续的文章里统一说明,此文不赘述。
我们还是看一下实际运行效果吧:
PS D:\008 rustpro\fibonacci> cargo runCompiling fibonacci v0.1.0 (D:\008 rustpro\fibonacci)Finished dev [unoptimized + debuginfo] target(s) in 0.71sRunning `target\debug\fibonacci.exe`
please enter fibonacci number:
2
number is 2
fibo(1) is 1
please enter fibonacci number:
5
number is 5
fibo(1) is 1
fibo(2) is 1
fibo(3) is 2
fibo(4) is 3
please enter fibonacci number:
10
number is 10
fibo(1) is 1
fibo(2) is 1
fibo(3) is 2
fibo(4) is 3
fibo(5) is 5
fibo(6) is 8
fibo(7) is 13
fibo(8) is 21
fibo(9) is 34
please enter fibonacci number:
r
thread 'main' panicked at src\main.rs:10:46:
err: ParseIntError { kind: InvalidDigit }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\fibonacci.exe` (exit code: 101)
总结一下,rust变量:
let x=5;//x不可变
let mut x=5;//x可变
let x=5;
let x='a';//x依旧不可变,但可以被重名者覆盖,且可不同数据类型
const x:i32=5;//常量需指定数据类型
相关文章:

Rust学习日记(二)变量的使用--结合--温度换算/斐波那契数列--实例
前言: 这是一个系列的学习笔记,会将笔者学习Rust语言的心得记录。 当然,这并非是流水账似的记录,而是结合实际程序项目的记录,如果你也对Rust感兴趣,那么我们可以一起交流探讨,使用Rust来构建程…...

html各个标签的使用
一、标签的分类 1、单标签和双标签 1. 单标签:<img> img br hr 2. 双标签:<div></div> div span <a></a> h p a 2、按照标签属性分类 1. 块标签:自己独占一行 h1~h6 p div 2. 行内(内联)标签 …...

android 混淆
# 指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。) -optimizationpasses 5 # 混淆时不会产生形形色色的类名(混淆时不使用大小写混合类名) -dontusemixedcaseclassnames # 指定不去忽略…...

旋转链表(C++解法)
题目 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 示例 1: 输入:head [1,2,3,4,5], k 2 输出:[4,5,1,2,3]示例 2: 输入:head [0,1,2], k 4 输出:[…...

AcWing 134:双端队列
【题目来源】https://www.acwing.com/problem/content/description/136/【题目描述】 达达现在碰到了一个棘手的问题,有 N 个整数需要排序。 达达手头能用的工具就是若干个双端队列。 她从 1 到 N 需要依次处理这 N 个数,对于每个数,达达能做…...

Spring Cloud Gateway 重写 URL
目录 1、简介 2、Spring Cloud Gateway 快速回顾 3、基于配置的 URL 重写 4、基于 DSL 的 URL 重写 5、测试 6、总结 1、简介 Spring Cloud Gateway 的常见用例是作为一个网关,代理一个或多个服务,从而为客户端提供更简单的消费方式。 本文将带你…...

【C语法学习】10 - scanf()函数
文章目录 0 前言1 函数原型2 参数2.1 格式字符串2.1.1 转换说明 2.2 参数列表 3 返回值4 读取机制4.1 基本概念4.2 转换说明4.3 读取过程4.4 读取示例4.5 多参数 6 示例6.1 示例16.2 示例26.3 示例36.4 示例4 0 前言 scanf()函数虽然使用起来较为灵活,但是其读取机…...

ffmpeg mp3截取命令,视频与mp3合成带音频视频命令
从00:00:03.500开始截取往后长度到结尾的mp3音频(这个更有用,测试好用) ffmpeg -i d:/c.mp3 -ss 00:00:03.500 d:/output.mp3 将两个音频合并成一个音频(测试好用) ffmpeg -i "concat:d:/c.mp3|d:/output.mp3&…...

文件夹还在,里面文件没了?问题这样解决
文件夹还在但文件无故消失怎么办?文件的消失对于我们来说可能是个令人沮丧且困惑的问题。有时候,我们可能会发现文件夹依然存在,但其中的文件却消失了。在这篇文章中,我们将探讨为什么电脑文件会无故消失的原因,并提供…...

使用 OpenCV 和 Tesseract OCR 进行车牌识别
您将了解自动车牌识别。我们将使用 Tesseract OCR 光学字符识别引擎(OCR 引擎)来自动识别车辆牌照中的文本。 Python-tesseract: Py-tesseract 是 Python 的光学字符识别 (OCR) 工具。也就是说,它将识别并“读取”图像中嵌入的文本。Python-tesseract 是 Google 的 Tessera…...

What exactly are the practices involved in DevOps?
目录 1. Continuous Integration (CI) 2. Continuous Deployment (CD) 3. Infrastructure as Code (IAC) 4. Configuration Management 5. Monitoring and Logging 6. Automated Testing 7. Collaboration and Communication 8. Microservices Architecture 9. Conta…...

Spring底层原理(五)
Spring底层原理(五) 本章内容 介绍Aware接口与InitializingBean接口、Bean的初始化与销毁、Scope Aware接口 作用:用于注入一些与容器相关的信息 类名作用BeanNameAware注入Bean的名称BeanFactoryAware注入BeanFactory容器ApplicationContextAware注入ApplicationContext容…...

算法的基本概念(数据结构与算法)
数据结构是指数据元素之间的关系和组织方式,在计算机科学中被广泛应用于存储和操作数据的方法和技术。 数据元素: 数据元素是构成数据的基本单位,可以是数字、字符、记录等。 数据项: 数据元素中的一个部分,表示一个属…...

高阶数据结构学习——LRU Cache
文章目录 1、了解LRU Cache(Least Recently Used缩写)2、代码实现 1、了解LRU Cache(Least Recently Used缩写) Cache是缓存,在磁盘和内存之间,内存和寄存器之间都存在,CPU和内存之间存在三级缓…...

代码冲突解决
远程仓库修改 本地代码修改 接下来我们push一下 如果使用IDE 冲突内容如下: 我们可以使用自带的工具进行修改 我们选择接受自己改动的即可 如果使用git工具怎么去处理呢 远程分支是这样 本地是这样的 add和commit之后,再pull,最后pus…...

c/c++程序的内存开辟时 的内存情况
我们写的代码都是要存放在内存空间中的,我们经常说堆区,静态区,还有栈区,相信很多人不是很明白,在今天这篇博客中让大家对它们有一个粗略的认识 1.栈区(static) 在执行函数时,函数内…...

【linux常用命令+vi编辑器_2023.11.3】
芯片开发 Linux/Unix(环境) EDA工具TCL(波形) SVN/GIT(版本控制) Makefile(脚本语言) Perl/Python(脚本语言) Vim/Gvim(编辑器) 命令…...

okhttp post请求 header post参数加密遇到的两个问题
如果你对于网络请求用了https后是否还有必要对参数加密有疑问可以看我上篇的文章:网络安全https 记得耐心看完,下面说问题: Caused by: java.lang.IllegalArgumentException: Unexpected char 0x0a 一开始以为是okhttp框架对特殊字符做了现在…...

什么是Webpack的loader和plugin?它们的作用是什么?
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

ESXi for ARM 最新下载地址
由于VMware决定关闭 flings.vmware.com 网站,内容被迁移到不同的地方,网站跳转到 Code Samples and PowerCLI Example Scripts | VMware - VMware {code} ESXi for ARM的下载地址迁移到了 https://customerconnect.vmware.com/downloads/get-download?…...

2. 网络之网络编程
网络编程 文章目录 网络编程1. UDP1.1 DatagramSocket1.1.1 DatagramSocket 构造方法1.1.2 DatagramSocket 方法: 1.2 DatagramPacket1.2.1 DatagramPacket构造方法1.2.2 DaragramPacket方法1.2.3InetSocketAddress API 1.3 UDP回显服务器1.3.1 框架结构1.3.2 读取请…...

工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化
业务流程是由“活动”(或称“工作任务”)构成的,在企业里的所有工作是不是都叫流程,或者属于流程的一部分,这个概念很绕,我觉得没有必要去做学究气的辨析。我曾经提出过一个从工作的两个特性(产…...

6-1 二叉排序树查找操作
description 本题要求实现二叉排序树的查找操作。 函数接口定义: BSTree SearchBST(BSTree T,ElemType e); 其中BSTree结构定义如下: typedef int ElemType; typedef struct BSTNode { ElemType data; struct BSTNode *lchild,*rchild; }BSTNode,*BS…...

服务上千家企业,矩阵通2.0重磅上线,全链路管理新媒体矩阵
自上线以来 矩阵通已服务了上千家企业级客户 覆盖汽车、家居、媒体、金融、教育等多个行业 矩阵通1.0时代 我们以“数据”为基座打造出10功能 帮助企业轻松管理新媒体矩阵 实现账号管理、数据分析、竞对监测、 人员考核、风险监管等需求 而现在 矩阵通2.0重磅上线 新增…...

【代码随想录】算法训练计划11
1、20. 有效的括号 题目: 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号…...

Jmeter之JSR223
一、JSR223组件 JSR是Java Specification Requests的缩写,意思是Java规范提案。JSR已成为Java界的一个重要标准. JSR223其实包含了有好几种组件,但是其用法都是一致的,并且都是执行一段代码,主要分类如下: JSR223 PreProcessor JSR223 Timer JSR223 S…...

c++23中的新功能之十八新增的属性
一、c23新的属性 在前面的分析中说过,各种语言的发展整体思路是一致的,即朝着更加实用、简单和更接近自然语言的方向在前进。c23中也在不断的完善和增加相关开发的一些属性和预编译处理指令,这样就可以让开发者在开发的过程中对程序进行控制…...

动手学深度学习:1.线性回归从0开始实现
动手学深度学习:1.线性回归从0开始实现 1.手动构造数据集2.小批量读取数据集3.初始化模型参数4.定义模型和损失函数5.小批量随机梯度下降更新6.训练完整代码 1.手动构造数据集 根据带有噪声的线性模型构造一个人造数据集,任务是使用这个有限样本的数据集…...

【计算机网络】应用层
应用层协议原理 客户-服务器体系结构: 特点:客户之间不能直接通信;服务器具有周知的,固定的地址,该地址称为IP地址。 配备大量主机的数据中心常被用于创建强大的虚拟服务器;P2P体系结构: 特点&…...

python 深度学习 解决遇到的报错问题9
本篇继python 深度学习 解决遇到的报错问题8-CSDN博客 目录 一、can only concatenate str (not "int") to str 二、cant convert np.ndarray of type numpy.object_. The only supported types are: float64, float32, float16, complex64, complex128, int64, in…...