当前位置: 首页 > news >正文

5 长度和距离计算模块(length.rs)

这段代码定义了一个泛型结构体 Length<T, Unit>,用于表示一维长度,其中 T 表示长度的数值类型,而 Unit 是一个编译时检查单位一致性的占位符类型,不会用于运行时表示长度的值。这个设计允许开发者在编译阶段确保不同单位之间的长度值在使用前进行了显式的单位转换。

一、length.rs文件源码

//! 用计量单位标记的一维长度。use crate::approxeq::ApproxEq;
use crate::approxord::{max, min};
use crate::num::Zero;
use crate::scale::Scale;use crate::num::One;
#[cfg(feature = "bytemuck")]
use bytemuck::{Pod, Zeroable};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::iter::Sum;
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Neg, Sub};
use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
use num_traits::{NumCast, Saturating};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};/*
一维距离,其值由“T”表示,测量单位为“Unit”。 
“T”可以是任何数字类型,例如像“u64”或“f32”这样的基元类型。 
“Unit”不用于表示“Length”值。它仅在编译时使用,以确保用一个单位存储的“Length”在用于需要不同单位的表达式之前被显式转换。它可能是一个没有值的类型,例如空枚举。 
您可以将“Length”乘以“Scale”,将其从一个单位转换为另一个单位。请参阅[`Scale`]结构体。
*/
#[repr(C)]
pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);impl<T: Clone, U> Clone for Length<T, U> {fn clone(&self) -> Self {Length(self.0.clone(), PhantomData)}
}impl<T: Copy, U> Copy for Length<T, U> {}#[cfg(feature = "serde")]
impl<'de, T, U> Deserialize<'de> for Length<T, U> where T: Deserialize<'de>,{fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,{Ok(Length(Deserialize::deserialize(deserializer)?, PhantomData))}
}#[cfg(feature = "serde")]
impl<T, U> Serialize for Length<T, U> where T: Serialize,{fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,{self.0.serialize(serializer)}
}#[cfg(feature = "arbitrary")]
impl<'a, T, U> arbitrary::Arbitrary<'a> for Length<T, U>
whereT: arbitrary::Arbitrary<'a>,
{fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {Ok(Length(arbitrary::Arbitrary::arbitrary(u)?, PhantomData))}
}#[cfg(feature = "bytemuck")]
unsafe impl<T: Zeroable, U> Zeroable for Length<T, U> {}#[cfg(feature = "bytemuck")]
unsafe impl<T: Pod, U: 'static> Pod for Length<T, U> {}impl<T, U> Length<T, U> {/// 将值与度量单位相关联。#[inline]pub const fn new(x: T) -> Self {Length(x, PhantomData)}
}impl<T: Clone, U> Length<T, U> {/// 从类中提取基值pub fn get(self) -> T {self.0}/// Cast the unit#[inline]pub fn cast_unit<V>(self) -> Length<T, V> {Length::new(self.0)}/// Linearly interpolate between this length and another length.////// # Example////// ```rust/// use euclid::default::Length;////// let from = Length::new(0.0);/// let to = Length::new(8.0);////// assert_eq!(from.lerp(to, -1.0), Length::new(-8.0));/// assert_eq!(from.lerp(to,  0.0), Length::new( 0.0));/// assert_eq!(from.lerp(to,  0.5), Length::new( 4.0));/// assert_eq!(from.lerp(to,  1.0), Length::new( 8.0));/// assert_eq!(from.lerp(to,  2.0), Length::new(16.0));/// ```#[inline]pub fn lerp(self, other: Self, t: T) -> SelfwhereT: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,{let one_t = T::one() - t.clone();Length::new(one_t * self.0.clone() + t * other.0)}
}impl<T: PartialOrd, U> Length<T, U> {/// Returns minimum between this length and another length.#[inline]pub fn min(self, other: Self) -> Self {min(self, other)}/// Returns maximum between this length and another length.#[inline]pub fn max(self, other: Self) -> Self {max(self, other)}
}impl<T: NumCast + Clone, U> Length<T, U> {/// Cast from one numeric representation to another, preserving the units.#[inline]pub fn cast<NewT: NumCast>(self) -> Length<NewT, U> {self.try_cast().unwrap()}/// Fallible cast from one numeric representation to another, preserving the units.pub fn try_cast<NewT: NumCast>(self) -> Option<Length<NewT, U>> {NumCast::from(self.0).map(Length::new)}
}impl<T: fmt::Debug, U> fmt::Debug for Length<T, U> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {self.0.fmt(f)}
}impl<T: Default, U> Default for Length<T, U> {#[inline]fn default() -> Self {Length::new(Default::default())}
}impl<T: Hash, U> Hash for Length<T, U> {fn hash<H: Hasher>(&self, h: &mut H) {self.0.hash(h);}
}// length + length
impl<T: Add, U> Add for Length<T, U> {type Output = Length<T::Output, U>;fn add(self, other: Self) -> Self::Output {Length::new(self.0 + other.0)}
}// length + &length
impl<T: Add + Copy, U> Add<&Self> for Length<T, U> {type Output = Length<T::Output, U>;fn add(self, other: &Self) -> Self::Output {Length::new(self.0 + other.0)}
}// length_iter.copied().sum()
impl<T: Add<Output = T> + Zero, U> Sum for Length<T, U> {fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {iter.fold(Self::zero(), Add::add)}
}// length_iter.sum()
impl<'a, T: 'a + Add<Output = T> + Copy + Zero, U: 'a> Sum<&'a Self> for Length<T, U> {fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {iter.fold(Self::zero(), Add::add)}
}// length += length
impl<T: AddAssign, U> AddAssign for Length<T, U> {fn add_assign(&mut self, other: Self) {self.0 += other.0;}
}// length - length
impl<T: Sub, U> Sub for Length<T, U> {type Output = Length<T::Output, U>;fn sub(self, other: Length<T, U>) -> Self::Output {Length::new(self.0 - other.0)}
}// length -= length
impl<T: SubAssign, U> SubAssign for Length<T, U> {fn sub_assign(&mut self, other: Self) {self.0 -= other.0;}
}// Saturating length + length and length - length.
impl<T: Saturating, U> Saturating for Length<T, U> {fn saturating_add(self, other: Self) -> Self {Length::new(self.0.saturating_add(other.0))}fn saturating_sub(self, other: Self) -> Self {Length::new(self.0.saturating_sub(other.0))}
}// length / length
impl<Src, Dst, T: Div> Div<Length<T, Src>> for Length<T, Dst> {type Output = Scale<T::Output, Src, Dst>;#[inline]fn div(self, other: Length<T, Src>) -> Self::Output {Scale::new(self.0 / other.0)}
}// length * scalar
impl<T: Mul, U> Mul<T> for Length<T, U> {type Output = Length<T::Output, U>;#[inline]fn mul(self, scale: T) -> Self::Output {Length::new(self.0 * scale)}
}// length *= scalar
impl<T: Copy + Mul<T, Output = T>, U> MulAssign<T> for Length<T, U> {#[inline]fn mul_assign(&mut self, scale: T) {*self = *self * scale;}
}// length / scalar
impl<T: Div, U> Div<T> for Length<T, U> {type Output = Length<T::Output, U>;#[inline]fn div(self, scale: T) -> Self::Output {Length::new(self.0 / scale)}
}// length /= scalar
impl<T: Copy + Div<T, Output = T>, U> DivAssign<T> for Length<T, U> {#[inline]fn div_assign(&mut self, scale: T) {*self = *self / scale;}
}// length * scaleFactor
impl<Src, Dst, T: Mul> Mul<Scale<T, Src, Dst>> for Length<T, Src> {type Output = Length<T::Output, Dst>;#[inline]fn mul(self, scale: Scale<T, Src, Dst>) -> Self::Output {Length::new(self.0 * scale.0)}
}// length / scaleFactor
impl<Src, Dst, T: Div> Div<Scale<T, Src, Dst>> for Length<T, Dst> {type Output = Length<T::Output, Src>;#[inline]fn div(self, scale: Scale<T, Src, Dst>) -> Self::Output {Length::new(self.0 / scale.0)}
}// -length
impl<U, T: Neg> Neg for Length<T, U> {type Output = Length<T::Output, U>;#[inline]fn neg(self) -> Self::Output {Length::new(-self.0)}
}impl<T: PartialEq, U> PartialEq for Length<T, U> {fn eq(&self, other: &Self) -> bool {self.0.eq(&other.0)}
}impl<T: PartialOrd, U> PartialOrd for Length<T, U> {fn partial_cmp(&self, other: &Self) -> Option<Ordering> {self.0.partial_cmp(&other.0)}
}impl<T: Eq, U> Eq for Length<T, U> {}impl<T: Ord, U> Ord for Length<T, U> {fn cmp(&self, other: &Self) -> Ordering {self.0.cmp(&other.0)}
}impl<T: Zero, U> Zero for Length<T, U> {#[inline]fn zero() -> Self {Length::new(Zero::zero())}
}impl<U, T: ApproxEq<T>> ApproxEq<T> for Length<T, U> {#[inline]fn approx_epsilon() -> T {T::approx_epsilon()}#[inline]fn approx_eq_eps(&self, other: &Length<T, U>, approx_epsilon: &T) -> bool {self.0.approx_eq_eps(&other.0, approx_epsilon)}
}#[cfg(test)]
mod tests {use super::Length;use crate::num::Zero;use crate::scale::Scale;use core::f32::INFINITY;use num_traits::Saturating;enum Inch {}enum Mm {}enum Cm {}enum Second {}#[cfg(feature = "serde")]mod serde {use super::*;extern crate serde_test;use self::serde_test::assert_tokens;use self::serde_test::Token;#[test]fn test_length_serde() {let one_cm: Length<f32, Mm> = Length::new(10.0);assert_tokens(&one_cm, &[Token::F32(10.0)]);}}#[test]fn test_clone() {// A cloned Length is a separate length with the state matching the// original Length at the point it was cloned.let mut variable_length: Length<f32, Inch> = Length::new(12.0);let one_foot = variable_length.clone();variable_length.0 = 24.0;assert_eq!(one_foot.get(), 12.0);assert_eq!(variable_length.get(), 24.0);}#[test]fn test_add() {let length1: Length<u8, Mm> = Length::new(250);let length2: Length<u8, Mm> = Length::new(5);assert_eq!((length1 + length2).get(), 255);assert_eq!((length1 + &length2).get(), 255);}#[test]fn test_sum() {type L = Length<f32, Mm>;let lengths = [L::new(1.0), L::new(2.0), L::new(3.0)];assert_eq!(lengths.iter().sum::<L>(), L::new(6.0));}#[test]fn test_addassign() {let one_cm: Length<f32, Mm> = Length::new(10.0);let mut measurement: Length<f32, Mm> = Length::new(5.0);measurement += one_cm;assert_eq!(measurement.get(), 15.0);}#[test]fn test_sub() {let length1: Length<u8, Mm> = Length::new(250);let length2: Length<u8, Mm> = Length::new(5);let result = length1 - length2;assert_eq!(result.get(), 245);}#[test]fn test_subassign() {let one_cm: Length<f32, Mm> = Length::new(10.0);let mut measurement: Length<f32, Mm> = Length::new(5.0);measurement -= one_cm;assert_eq!(measurement.get(), -5.0);}#[test]fn test_saturating_add() {let length1: Length<u8, Mm> = Length::new(250);let length2: Length<u8, Mm> = Length::new(6);let result = length1.saturating_add(length2);assert_eq!(result.get(), 255);}#[test]fn test_saturating_sub() {let length1: Length<u8, Mm> = Length::new(5);let length2: Length<u8, Mm> = Length::new(10);let result = length1.saturating_sub(length2);assert_eq!(result.get(), 0);}#[test]fn test_division_by_length() {// Division results in a Scale from denominator units// to numerator units.let length: Length<f32, Cm> = Length::new(5.0);let duration: Length<f32, Second> = Length::new(10.0);let result = length / duration;let expected: Scale<f32, Second, Cm> = Scale::new(0.5);assert_eq!(result, expected);}#[test]fn test_multiplication() {let length_mm: Length<f32, Mm> = Length::new(10.0);let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);let result = length_mm * cm_per_mm;let expected: Length<f32, Cm> = Length::new(1.0);assert_eq!(result, expected);}#[test]fn test_multiplication_with_scalar() {let length_mm: Length<f32, Mm> = Length::new(10.0);let result = length_mm * 2.0;let expected: Length<f32, Mm> = Length::new(20.0);assert_eq!(result, expected);}#[test]fn test_multiplication_assignment() {let mut length: Length<f32, Mm> = Length::new(10.0);length *= 2.0;let expected: Length<f32, Mm> = Length::new(20.0);assert_eq!(length, expected);}#[test]fn test_division_by_scalefactor() {let length: Length<f32, Cm> = Length::new(5.0);let cm_per_second: Scale<f32, Second, Cm> = Scale::new(10.0);let result = length / cm_per_second;let expected: Length<f32, Second> = Length::new(0.5);assert_eq!(result, expected);}#[test]fn test_division_by_scalar() {let length: Length<f32, Cm> = Length::new(5.0);let result = length / 2.0;let expected: Length<f32, Cm> = Length::new(2.5);assert_eq!(result, expected);}#[test]fn test_division_assignment() {let mut length: Length<f32, Mm> = Length::new(10.0);length /= 2.0;let expected: Length<f32, Mm> = Length::new(5.0);assert_eq!(length, expected);}#[test]fn test_negation() {let length: Length<f32, Cm> = Length::new(5.0);let result = -length;let expected: Length<f32, Cm> = Length::new(-5.0);assert_eq!(result, expected);}#[test]fn test_cast() {let length_as_i32: Length<i32, Cm> = Length::new(5);let result: Length<f32, Cm> = length_as_i32.cast();let length_as_f32: Length<f32, Cm> = Length::new(5.0);assert_eq!(result, length_as_f32);}#[test]fn test_equality() {let length_5_point_0: Length<f32, Cm> = Length::new(5.0);let length_5_point_1: Length<f32, Cm> = Length::new(5.1);let length_0_point_1: Length<f32, Cm> = Length::new(0.1);assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);assert!(length_5_point_0 != length_5_point_1);}#[test]fn test_order() {let length_5_point_0: Length<f32, Cm> = Length::new(5.0);let length_5_point_1: Length<f32, Cm> = Length::new(5.1);let length_0_point_1: Length<f32, Cm> = Length::new(0.1);assert!(length_5_point_0 < length_5_point_1);assert!(length_5_point_0 <= length_5_point_1);assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);assert!(length_5_point_1 > length_5_point_0);assert!(length_5_point_1 >= length_5_point_0);assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);}#[test]fn test_zero_add() {type LengthCm = Length<f32, Cm>;let length: LengthCm = Length::new(5.0);let result = length - LengthCm::zero();assert_eq!(result, length);}#[test]fn test_zero_division() {type LengthCm = Length<f32, Cm>;let length: LengthCm = Length::new(5.0);let length_zero: LengthCm = Length::zero();let result = length / length_zero;let expected: Scale<f32, Cm, Cm> = Scale::new(INFINITY);assert_eq!(result, expected);}
}

二、结构体定义

#[repr(C)]
pub struct Length<T, Unit>(pub T, #[doc(hidden)] pub PhantomData<Unit>);
  • #[repr©]:保证结构体在内存中的布局与C语言兼容,通常用于确保与C/C++代码或外部接口的二进制兼容性。
  • PhantomData:一个零大小的类型,用于在编译时携带类型信息,而不会增加结构体的大小。这里用于确保单位的一致性。

三、实现Clone

impl<T: Clone, U> Clone for Length<T, U> {fn clone(&self) -> Self {Length(self.0.clone(), PhantomData)}
}
  • 这段代码实现了Clone trait,允许Length类型的值被克隆。
  • PhantomData的实例化应使用PhantomData::,而不是直接使用PhantomData(虽然Rust编译器通常可以推断)。

四、cast和try_cast方法

impl<T: NumCast + Clone, U> Length<T, U> {/// Cast from one numeric representation to another, preserving the units.#[inline]pub fn cast<NewT: NumCast>(self) -> Length<NewT, U> {self.try_cast().unwrap()}/// Fallible cast from one numeric representation to another, preserving the units.pub fn try_cast<NewT: NumCast>(self) -> Option<Length<NewT, U>> {NumCast::from(self.0).map(Length::new)}
}
  • 这里我们使用了num_traits::NumCast trait来实现数值类型之间的转换。
  • cast方法调用try_cast并解包Option,这意味着如果转换失败,程序将会panic。
  • try_cast方法尝试将Length的数值部分从类型T转换为NewT,如果成功,则使用新的数值和原始的单位类型U创建一个新的Length值。

五、其他trait实现

  • fmt::Debug:为Length实现Debug trait,使得Length值可以格式化输出。
  • Default:为Length实现Default trait,允许使用default()方法创建默认值的Length实例。
  • Hash:为Length实现Hash trait,使得Length值可以被哈希。
  • Length + Length 的加法
  • Length + &Length 的加法
  • Length 迭代器的求和(Sum)实现(针对可复制的情况)
  • &Length 迭代器的求和(Sum)实现
  • Length += Length 的加法
  • 减法实现
  • 比较特性(PartialEq, PartialOrd, Eq, Ord)的实现
  • 零值特性(Zero)的实现
  • 近似相等特性(ApproxEq)的实现
    #六、结束语
    这个结构体不仅提供了数值和单位的泛型表示,还通过实现各种 trait 来支持丰富的操作,如加减、克隆、比较和哈希等。这使得 Length<T, U> 能够与 Rust 标准库中的许多算法和数据结构无缝协作,同时保持了泛型性和类型安全。

相关文章:

5 长度和距离计算模块(length.rs)

这段代码定义了一个泛型结构体 Length<T, Unit>&#xff0c;用于表示一维长度&#xff0c;其中 T 表示长度的数值类型&#xff0c;而 Unit 是一个编译时检查单位一致性的占位符类型&#xff0c;不会用于运行时表示长度的值。这个设计允许开发者在编译阶段确保不同单位之间…...

ollama改模型的存盘目录解决下载大模型报c:盘空间不足的问题

使用Ollama和Open WebUI快速玩转大模型&#xff1a;简单快捷的尝试各种llm大模型&#xff0c;比如DeepSeek r1&#xff0c;非常简单方便&#xff0c;参见&#xff1a;使用Ollama和Open WebUI快速玩转大模型&#xff1a;简单快捷的尝试各种llm大模型&#xff0c;比如DeepSeek r1…...

OSCP:常见文件传输方法

在渗透测试过程中&#xff0c;文件传输是一个关键环节&#xff0c;涉及不同的协议和工具&#xff0c;本文整理了 Linux 和 Windows 系统下常见的文件传输方法&#xff0c;并提供相应的命令示例。 通用文件传输方式 Base64 编码传输 Base64 可用于跨平台传输文件&#xff0c;…...

B站吴恩达机器学习笔记

机器学习视频地址&#xff1a; 4.5 线性回归中的梯度下降_哔哩哔哩_bilibili 机器学习分类&#xff1a; 1. 有监督学习&#xff08;Supervised Learning&#xff09; 在有监督学习中&#xff0c;训练数据包含了输入特征和正确的输出标签&#xff0c;模型通过这些带有标签的…...

Java 性能优化与新特性

Java学习资料 Java学习资料 Java学习资料 一、引言 Java 作为一门广泛应用于企业级开发、移动应用、大数据等多个领域的编程语言&#xff0c;其性能和特性一直是开发者关注的重点。随着软件系统的规模和复杂度不断增加&#xff0c;对 Java 程序性能的要求也越来越高。同时&a…...

【计算机网络】host文件

host文件的主要功能&#xff1a; 域名解析 本地映射&#xff1a;host文件的主要功能是将**域名映射到相应的 IP 地址**。当计算机需要访问一个网站或服务时&#xff0c;它会首先在 host文件中查找该域名对应的 IP 地址。如果在 host文件中找到了匹配的域名和 IP 地址映射&…...

【C语言】在Windows上为可执行文件.exe添加自定义图标

本文详细介绍了在 Windows 环境下,如何为使用 GCC 编译器编译的 C程序 添加自定义图标,从而生成带有图标的 .exe 可执行文件。通过本文的指导,读者可以了解到所需的条件以及具体的操作步骤,使生成的程序更具专业性和个性化。 目录 1. 准备条件2. 具体步骤步骤 1: 准备资源文…...

爬虫基础(五)爬虫基本原理

目录 一、爬虫是什么 二、爬虫过程 &#xff08;1&#xff09;获取网页 &#xff08;2&#xff09;提取信息 &#xff08;3&#xff09;保存数据 三、爬虫可爬的数据 四、爬虫问题 一、爬虫是什么 互联网&#xff0c;后面有个网字&#xff0c;我们可以把它看成一张蜘蛛网…...

力扣【1049. 最后一块石头的重量 II】Java题解(背包问题)

让石头分成重量相同的两堆&#xff08;尽可能相同&#xff09;&#xff0c;相撞之后剩下的石头就是最小的。进一步转化成容量为重量总喝一半的背包最多可以装多少质量的石头。这样就转化成了背包问题。 最后求结果时&#xff0c;我们所最多能装的时dp[target]&#xff0c;那另一…...

FFmpeg rtmp推流直播

文章目录 rtmp协议RTMP协议组成RTMP的握手过程RTMP流的创建RTMP消息格式Chunking(Message 分块) rtmp服务器搭建Nginx服务器配置Nginx服务器 librtmp库编译推流 rtmp协议 RTMP&#xff08;Real Time Messaging Protocol&#xff09;是由Adobe公司基于Flash Player播放器对应的…...

WordPress Icegram Express插件Sql注入漏洞复现(CVE-2024-2876)(附脚本)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...

重构字符串(767)

767. 重构字符串 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:string reorganizeString(string s){string res;//因为1 < s.length < 500 &#xff0c; uint64_t 类型足够uint16_t n s.size();if (n 0) {return res;}unordere…...

IO进程线程复习

IO进程线程复习...

深入理解Linux内核的虚拟地址到物理地址转换机制及缓存优化

在现代计算机系统中,虚拟地址到物理地址的转换是操作系统内存管理的重要组成部分。特别是在基于x86_64架构的Linux系统上,这一转换过程及其相关的缓存机制对系统性能和稳定性至关重要。本文将深入探讨Debian 10上运行Linux 4.19内核时,这些机制的实现细节,特别是页表管理、…...

2025年01月29日Github流行趋势

项目名称&#xff1a;Janus 项目地址url&#xff1a;https://github.com/deepseek-ai/Janus项目语言&#xff1a;Python历史star数&#xff1a;9350今日star数&#xff1a;5969项目维护者&#xff1a;learningpro, hills-code, TheOneTrueGuy, mowentian, soloice项目简介&…...

yolov11、yolov8部署的7种方法(yolov11、yolov8部署rknn的7种方法),一天一种部署方法,7天入门部署

由于涉及量化、部署两个领域&#xff0c;本博文难免有不对之处&#xff0c;欢迎指正。 本博客对 yolov11&#xff08;yolov8&#xff09;尝试了7种不同的部署方法&#xff0c;在最基础的模型上一步一步的去掉解码相关的操作&#xff08;移到后处理种进行&#xff09;&#xff0…...

【ArcGIS遇上Python】批量提取多波段影像至单个波段

本案例基于ArcGIS python,将landsat影像的7个波段影像数据,批量提取至单个波段。 相关阅读:【ArcGIS微课1000例】0141:提取多波段影像中的单个波段 文章目录 一、数据准备二、效果比对二、python批处理1. 编写python代码2. 运行代码一、数据准备 实验数据及完整的python位…...

Node.js MySQL:深度解析与最佳实践

Node.js MySQL:深度解析与最佳实践 引言 Node.js作为一种流行的JavaScript运行时环境,以其轻量级、高性能和事件驱动模型受到开发者的青睐。MySQL则是一款功能强大的关系型数据库管理系统,广泛应用于各种规模的应用程序中。本文将深入探讨Node.js与MySQL的集成,分析其优势…...

wordpress外贸独立站常用询盘软件

LiveChat LiveChat是一家提供实时聊天软件的公司&#xff0c;帮助企业通过其平台与客户进行即时通讯&#xff0c;提高客户满意度和忠诚度。他们的产品允许企业在网站、应用程序或电子邮件等多个渠道与客户互动&#xff0c;从而提升客户体验并促进销售增长。 LiveChat的软件特…...

Kotlin 委托详解

Kotlin 委托详解 引言 Kotlin 作为一种现代化的编程语言&#xff0c;在 Android 开发等领域得到了广泛的应用。在 Kotlin 中&#xff0c;委托&#xff08;Delegation&#xff09;是一种强大的特性&#xff0c;它可以让我们以更简洁的方式实现代码的复用和扩展。本文将详细解析…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...