8 比例缩放(scale.rs)
scale.rs代码是几何变换库euclid中典型的数据结构和方法的例子,用于处理二维和三维空间中的缩放变换。
一、scale.rs文件源码
//! A type-checked scaling factor between units.use crate::num::One;use crate::approxord::{max, min};
use crate::{Box2D, Box3D, Point2D, Point3D, Rect, Size2D, Vector2D};use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Sub};#[cfg(feature = "bytemuck")]
use bytemuck::{Pod, Zeroable};
use num_traits::NumCast;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};/// A scaling factor between two different units of measurement.
///
/// This is effectively a type-safe float, intended to be used in combination with other types like
/// `length::Length` to enforce conversion between systems of measurement at compile time.
///
/// `Src` and `Dst` represent the units before and after multiplying a value by a `Scale`. They
/// may be types without values, such as empty enums. For example:
///
/// ```rust
/// use euclid::Scale;
/// use euclid::Length;
/// enum Mm {};
/// enum Inch {};
///
/// let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);
///
/// let one_foot: Length<f32, Inch> = Length::new(12.0);
/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
/// ```
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde",serde(bound(serialize = "T: serde::Serialize",deserialize = "T: serde::Deserialize<'de>"))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);impl<T, Src, Dst> Scale<T, Src, Dst> {#[inline]pub const fn new(x: T) -> Self {Scale(x, PhantomData)}/// 创建标识比例(1.0)#[inline]pub fn identity() -> Selfwhere T: One,{Scale::new(T::one())}/// Returns the given point transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, point2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));/// ```#[inline]pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>whereT: Copy + Mul,{Point2D::new(point.x * self.0, point.y * self.0)}/// Returns the given point transformed by this scale.#[inline]pub fn transform_point3d(self, point: Point3D<T, Src>) -> Point3D<T::Output, Dst>whereT: Copy + Mul,{Point3D::new(point.x * self.0, point.y * self.0, point.z * self.0)}/// Returns the given vector transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, vec2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));/// ```#[inline]pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>whereT: Copy + Mul,{Vector2D::new(vec.x * self.0, vec.y * self.0)}/// Returns the given size transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, size2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));/// ```#[inline]pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>whereT: Copy + Mul,{Size2D::new(size.width * self.0, size.height * self.0)}/// Returns the given rect transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, rect};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));/// ```#[inline]pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>whereT: Copy + Mul,{Rect::new(self.transform_point(rect.origin),self.transform_size(rect.size),)}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box2d(self, b: &Box2D<T, Src>) -> Box2D<T::Output, Dst>whereT: Copy + Mul,{Box2D {min: self.transform_point(b.min),max: self.transform_point(b.max),}}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box3d(self, b: &Box3D<T, Src>) -> Box3D<T::Output, Dst>where T: Copy + Mul,{Box3D {min: self.transform_point3d(b.min),max: self.transform_point3d(b.max),}}/// Returns `true` if this scale has no effect.////// # Example////// ```rust/// use euclid::Scale;/// use euclid::num::One;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);/// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);////// assert_eq!(cm_per_mm.is_identity(), false);/// assert_eq!(mm_per_mm.is_identity(), true);/// assert_eq!(mm_per_mm, Scale::one());/// ```#[inline]pub fn is_identity(self) -> boolwhere T: PartialEq + One,{self.0 == T::one()}/// Returns the underlying scalar scale factor.#[inline]pub fn get(self) -> T {self.0}/// The inverse Scale (1.0 / self).////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);////// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));/// ```pub fn inverse(self) -> Scale<T::Output, Dst, Src>whereT: One + Div,{let one: T = One::one();Scale::new(one / self.0)}
}impl<T: PartialOrd, Src, Dst> Scale<T, Src, Dst> {#[inline]pub fn min(self, other: Self) -> Self {Self::new(min(self.0, other.0))}#[inline]pub fn max(self, other: Self) -> Self {Self::new(max(self.0, other.0))}/// Returns the point each component of which clamped by corresponding/// components of `start` and `end`.////// Shortcut for `self.max(start).min(end)`.#[inline]pub fn clamp(self, start: Self, end: Self) -> SelfwhereT: Copy,{self.max(start).min(end)}
}impl<T: NumCast, Src, Dst> Scale<T, Src, Dst> {/// Cast from one numeric representation to another, preserving the units.////// # Panics////// If the source value cannot be represented by the target type `NewT`, then/// method panics. Use `try_cast` if that must be case.////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.cast::<f32>(), Scale::new(10.0));/// ```/// That conversion will panic, because `i32` not enough to store such big numbers:/// ```rust,should_panic/// use euclid::Scale;/// enum Mm {};// millimeter = 10^-2 meters/// enum Em {};// exameter = 10^18 meters////// // Panics/// let to_em: Scale<i32, Mm, Em> = Scale::new(10e20).cast();/// ```#[inline]pub fn cast<NewT: NumCast>(self) -> Scale<NewT, Src, Dst> {self.try_cast().unwrap()}/// Fallible cast from one numeric representation to another, preserving the units./// If the source value cannot be represented by the target type `NewT`, then `None`/// is returned.////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};/// enum Em {};// Exameter = 10^18 meters////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);/// let to_em: Scale<f32, Mm, Em> = Scale::new(10e20);////// assert_eq!(to_mm.try_cast::<f32>(), Some(Scale::new(10.0)));/// // Integer to small to store that number/// assert_eq!(to_em.try_cast::<i32>(), None);/// ```pub fn try_cast<NewT: NumCast>(self) -> Option<Scale<NewT, Src, Dst>> {NumCast::from(self.0).map(Scale::new)}
}#[cfg(feature = "arbitrary")]
impl<'a, T, Src, Dst> arbitrary::Arbitrary<'a> for Scale<T, Src, Dst>
whereT: arbitrary::Arbitrary<'a>,
{fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {Ok(Scale::new(arbitrary::Arbitrary::arbitrary(u)?))}
}#[cfg(feature = "bytemuck")]
unsafe impl<T: Zeroable, Src, Dst> Zeroable for Scale<T, Src, Dst> {}#[cfg(feature = "bytemuck")]
unsafe impl<T: Pod, Src: 'static, Dst: 'static> Pod for Scale<T, Src, Dst> {}// scale0 * scale1
// (A,B) * (B,C) = (A,C)
impl<T: Mul, A, B, C> Mul<Scale<T, B, C>> for Scale<T, A, B> {type Output = Scale<T::Output, A, C>;#[inline]fn mul(self, other: Scale<T, B, C>) -> Self::Output {Scale::new(self.0 * other.0)}
}// scale0 + scale1
impl<T: Add, Src, Dst> Add for Scale<T, Src, Dst> {type Output = Scale<T::Output, Src, Dst>;#[inline]fn add(self, other: Scale<T, Src, Dst>) -> Self::Output {Scale::new(self.0 + other.0)}
}// scale0 - scale1
impl<T: Sub, Src, Dst> Sub for Scale<T, Src, Dst> {type Output = Scale<T::Output, Src, Dst>;#[inline]fn sub(self, other: Scale<T, Src, Dst>) -> Self::Output {Scale::new(self.0 - other.0)}
}// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
// https://github.com/rust-lang/rust/issues/26925impl<T: PartialEq, Src, Dst> PartialEq for Scale<T, Src, Dst> {fn eq(&self, other: &Scale<T, Src, Dst>) -> bool {self.0 == other.0}
}impl<T: Eq, Src, Dst> Eq for Scale<T, Src, Dst> {}impl<T: PartialOrd, Src, Dst> PartialOrd for Scale<T, Src, Dst> {fn partial_cmp(&self, other: &Self) -> Option<Ordering> {self.0.partial_cmp(&other.0)}
}impl<T: Ord, Src, Dst> Ord for Scale<T, Src, Dst> {fn cmp(&self, other: &Self) -> Ordering {self.0.cmp(&other.0)}
}impl<T: Clone, Src, Dst> Clone for Scale<T, Src, Dst> {fn clone(&self) -> Scale<T, Src, Dst> {Scale::new(self.0.clone())}
}impl<T: Copy, Src, Dst> Copy for Scale<T, Src, Dst> {}impl<T: fmt::Debug, Src, Dst> fmt::Debug for Scale<T, Src, Dst> {fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {self.0.fmt(f)}
}impl<T: Default, Src, Dst> Default for Scale<T, Src, Dst> {fn default() -> Self {Self::new(T::default())}
}impl<T: Hash, Src, Dst> Hash for Scale<T, Src, Dst> {fn hash<H: Hasher>(&self, state: &mut H) {self.0.hash(state);}
}impl<T: One, Src, Dst> One for Scale<T, Src, Dst> {#[inline]fn one() -> Self {Scale::new(T::one())}
}#[cfg(test)]
mod tests {use super::Scale;enum Inch {}enum Cm {}enum Mm {}#[test]fn test_scale() {let mm_per_inch: Scale<f32, Inch, Mm> = Scale::new(25.4);let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);let mm_per_cm: Scale<f32, Cm, Mm> = cm_per_mm.inverse();assert_eq!(mm_per_cm.get(), 10.0);let one: Scale<f32, Mm, Mm> = cm_per_mm * mm_per_cm;assert_eq!(one.get(), 1.0);let one: Scale<f32, Cm, Cm> = mm_per_cm * cm_per_mm;assert_eq!(one.get(), 1.0);let cm_per_inch: Scale<f32, Inch, Cm> = mm_per_inch * cm_per_mm;// mm cm cm// ---- x ---- = ----// inch mm inchassert_eq!(cm_per_inch, Scale::new(2.54));let a: Scale<isize, Inch, Inch> = Scale::new(2);let b: Scale<isize, Inch, Inch> = Scale::new(3);assert_ne!(a, b);assert_eq!(a, a.clone());assert_eq!(a.clone() + b.clone(), Scale::new(5));assert_eq!(a - b, Scale::new(-1));// Clampassert_eq!(Scale::identity().clamp(a, b), a);assert_eq!(Scale::new(5).clamp(a, b), b);let a = Scale::<f32, Inch, Inch>::new(2.0);let b = Scale::<f32, Inch, Inch>::new(3.0);let c = Scale::<f32, Inch, Inch>::new(2.5);assert_eq!(c.clamp(a, b), c);}
}
二、结构体定义
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde",serde(bound(serialize = "T: serde::Serialize",deserialize = "T: serde::Deserialize<'de>"))
)]
pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);
上面代码定义了一个使用Rust语言特性的泛型结构体Scale,这个结构体不仅使用了Rust的条件编译指令,还考虑了序列化/反序列化的能力,如果项目中启用了serde特性。下面是对这段代码的详细解释:
- #[repr( C )]:这个属性指定了结构体应该使用C语言的布局规则。这意味着结构体的内存布局将与C语言中的等效结构相匹配,这对于与C语言代码交互或与需要特定内存布局的系统API交互非常有用。
- #[cfg_attr(feature = “serde”, derive(Serialize, Deserialize))]:这是条件编译属性的一个示例。如果项目配置了serde特性(通常在Cargo.toml文件中通过features部分指定),那么将为这个结构体派生Serialize和Deserialize特性。这两个特性来自serde库,允许结构体实例被序列化为JSON、RON等格式或从这些格式反序列化。
- #[cfg_attr(… serde(bound(…)) )]:这部分进一步细化了serde特性的条件编译。它指定了当序列化或反序列化时,泛型参数T必须满足的条件。具体来说,如果正在序列化,T必须实现serde::Serialize;如果正在反序列化,T必须实现serde::Deserialize<'de>。这里,'de是一个生命周期参数,它是反序列化过程中使用的,表明反序列化操作与特定数据的生命周期相关联。
- pub struct Scale<T, Src, Dst>(pub T, #[doc(hidden)] pub PhantomData<(Src, Dst)>);:这是Scale结构体的定义。它是一个泛型结构体,有三个类型参数:T、Src和Dst。结构体内部包含两个字段:
- 第一个字段是公开的(pub T),意味着它可以被外部访问。
- 第二个字段是PhantomData<(Src, Dst)>,它被标记为#[doc(hidden)],意味着在生成的文档中这个字段将被隐藏。PhantomData是一个特殊的类型,用于在类型系统中表达所有权、借用或生命周期,但不占用任何运行时空间。在这里,它用于表示Scale结构体与Src和Dst类型有关联,尽管这两个类型在运行时并不实际存储任何数据。
- 总结:这段代码定义了一个条件编译支持序列化/反序列化,同时遵循C语言内存布局规则的泛型结构体,用于在Rust代码中表示某种形式的缩放或转换操作,其中T代表缩放或转换的值类型,而Src和Dst则用于在类型系统中表达源和目标类型的信息。
三、对应方法
方法源码
impl<T, Src, Dst> Scale<T, Src, Dst> {#[inline]pub const fn new(x: T) -> Self {Scale(x, PhantomData)}/// 创建标识比例(1.0)#[inline]pub fn identity() -> Selfwhere T: One,{Scale::new(T::one())}/// Returns the given point transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, point2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_point(point2(42, -42)), point2(420, -420));/// ```#[inline]pub fn transform_point(self, point: Point2D<T, Src>) -> Point2D<T::Output, Dst>whereT: Copy + Mul,{Point2D::new(point.x * self.0, point.y * self.0)}/// Returns the given point transformed by this scale.#[inline]pub fn transform_point3d(self, point: Point3D<T, Src>) -> Point3D<T::Output, Dst>whereT: Copy + Mul,{Point3D::new(point.x * self.0, point.y * self.0, point.z * self.0)}/// Returns the given vector transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, vec2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_vector(vec2(42, -42)), vec2(420, -420));/// ```#[inline]pub fn transform_vector(self, vec: Vector2D<T, Src>) -> Vector2D<T::Output, Dst>whereT: Copy + Mul,{Vector2D::new(vec.x * self.0, vec.y * self.0)}/// Returns the given size transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, size2};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_size(size2(42, -42)), size2(420, -420));/// ```#[inline]pub fn transform_size(self, size: Size2D<T, Src>) -> Size2D<T::Output, Dst>whereT: Copy + Mul,{Size2D::new(size.width * self.0, size.height * self.0)}/// Returns the given rect transformed by this scale.////// # Example////// ```rust/// use euclid::{Scale, rect};/// enum Mm {};/// enum Cm {};////// let to_mm: Scale<i32, Cm, Mm> = Scale::new(10);////// assert_eq!(to_mm.transform_rect(&rect(1, 2, 42, -42)), rect(10, 20, 420, -420));/// ```#[inline]pub fn transform_rect(self, rect: &Rect<T, Src>) -> Rect<T::Output, Dst>whereT: Copy + Mul,{Rect::new(self.transform_point(rect.origin),self.transform_size(rect.size),)}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box2d(self, b: &Box2D<T, Src>) -> Box2D<T::Output, Dst>whereT: Copy + Mul,{Box2D {min: self.transform_point(b.min),max: self.transform_point(b.max),}}/// Returns the given box transformed by this scale.#[inline]pub fn transform_box3d(self, b: &Box3D<T, Src>) -> Box3D<T::Output, Dst>where T: Copy + Mul,{Box3D {min: self.transform_point3d(b.min),max: self.transform_point3d(b.max),}}/// Returns `true` if this scale has no effect.////// # Example////// ```rust/// use euclid::Scale;/// use euclid::num::One;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Mm, Cm> = Scale::new(0.1);/// let mm_per_mm: Scale<f32, Mm, Mm> = Scale::new(1.0);////// assert_eq!(cm_per_mm.is_identity(), false);/// assert_eq!(mm_per_mm.is_identity(), true);/// assert_eq!(mm_per_mm, Scale::one());/// ```#[inline]pub fn is_identity(self) -> boolwhere T: PartialEq + One,{self.0 == T::one()}/// Returns the underlying scalar scale factor.#[inline]pub fn get(self) -> T {self.0}/// The inverse Scale (1.0 / self).////// # Example////// ```rust/// use euclid::Scale;/// enum Mm {};/// enum Cm {};////// let cm_per_mm: Scale<f32, Cm, Mm> = Scale::new(0.1);////// assert_eq!(cm_per_mm.inverse(), Scale::new(10.0));/// ```pub fn inverse(self) -> Scale<T::Output, Dst, Src>whereT: One + Div,{let one: T = One::one();Scale::new(one / self.0)}
}
2、new 方法:
这是一个常量函数,用于创建一个新的 Scale 实例。它接受一个类型为 T 的参数 x 作为缩放因子。
3、identity 方法:
用于创建一个表示没有缩放的 Scale 实例(即缩放因子为 1.0)。这需要 T 类型实现 One trait,该 trait 提供了一个获取类型中“1”的方法。
4、transform_point 方法:
用于将二维点(Point2D<T, Src>)根据缩放因子变换到新的单位系统(Dst)。这个方法要求 T 类型实现 Copy 和 Mul traits,以便可以复制和乘法操作。
5、transform_point3d 方法:
类似于 transform_point,但是用于三维点(Point3D<T, Src>)。
6、is_identity 方法:
检查当前的缩放因子是否为 1.0(即是否没有缩放)。这要求 T 类型实现 PartialEq 和 One traits。
7、get 方法:
返回缩放因子 x。
8、inverse 方法:
返回当前缩放的逆缩放,即将 1.0 / self.0 作为新的缩放因子。这要求 T 类型实现 One 和 Div traits。
9、min和max方法的实现:
min和max方法分别返回两个Scale实例之间较小或较大的那个。它们使用内部存储的值(self.0)来调用标准库中的min和max函数。
10、clamp方法的实现:
clamp方法将当前Scale实例的每个分量限制在start和end指定的范围内。这是通过先对start使用max方法,然后对end使用min方法来实现的,从而确保结果位于start和end之间。
11、NumCast trait相关的实现:
这部分代码被注释掉了,似乎原本打算为Scale实现一个与数值类型转换相关的功能,允许从一种数值表示转换到另一种,但具体的实现被省略了。
12、partial_cmp、cmp方法的实现:
- partial_cmp方法提供了一个可选的比较结果,这在类型T只能部分排序时非常有用(例如,浮点数与NaN的比较)。
- cmp方法提供了一个确定性的比较结果,要求T必须完全可排序(实现Ord trait)。
13、Clone、Copy trait的实现:
为Scale实现了Clone和Copy trait,这取决于T是否也实现了这些trait。如果T可以克隆或复制,那么Scale<T, Src, Dst>也可以。
14、Debug trait的实现:
为Scale实现了Debug trait,允许其实例使用{:?}格式化时打印调试信息。这依赖于T也实现了Debug trait。
15、Default trait的实现:
为Scale实现了Default trait,提供了一个默认构造函数,它依赖于T也实现了Default trait。
16、Hash trait的实现:
为Scale实现了Hash trait,允许其实例被哈希。这依赖于T也实现了Hash trait。
17、One trait的实现:
为Scale实现了One trait,提供了一个单位元素的构造函数(即值为1的Scale实例)。这依赖于T也实现了One trait。
相关文章:
8 比例缩放(scale.rs)
scale.rs代码是几何变换库euclid中典型的数据结构和方法的例子,用于处理二维和三维空间中的缩放变换。 一、scale.rs文件源码 //! A type-checked scaling factor between units.use crate::num::One;use crate::approxord::{max, min}; use crate::{Box2D, Box3D…...
二分 机器人的跳跃问题
二段性:找到一个值,大于此值的时候都成立,小于的时候都不成立 更新的方式只有两种,左边的mid更新不需要1;右边的mid更新需要1 //对能量进行二分,确定能量的范围 //特判防止溢出int #include<bits/stdc.h> using…...
Hive:复杂数据类型之Map函数
Map函数 是Hive里面的一种复杂数据类型, 用于存储键值对集合。Map中的键和值可以是基础类型或复合类型,这使得Map在处理需要关联存储信息的数据时非常有用。 定义map时,需声明2个属性: key 和 value , map中是 key value 组成一个元素 key-value, key必须为原始类…...
R 字符串:深入理解与高效应用
R 字符串:深入理解与高效应用 引言 在R语言中,字符串是数据处理和编程中不可或缺的一部分。无论是数据清洗、数据转换还是数据分析,字符串的处理都是基础技能。本文将深入探讨R语言中的字符串概念,包括其基本操作、常见函数以及高效应用方法。 字符串基本概念 字符串定…...
设计模式Python版 桥接模式
文章目录 前言一、桥接模式二、桥接模式示例三、桥接模式与适配器模式的联用 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&…...
记5(一元逻辑回归+线性分类器+多元逻辑回归
目录 1、一元逻辑回归2、线性可分&线性不可分3、Iris数据集实现多元逻辑回归4、绘制分类图5、鸢尾花分类图6、多分类问题:(softmax回归)6.1、编码:自然顺序码、独热编码、独冷编码6.2、二/多分类问题:6.3、softmax…...
【Python】第七弹---Python基础进阶:深入字典操作与文件处理技巧
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【MySQL】【Python】 目录 1、字典 1.1、字典是什么 1.2、创建字典 1.3、查找 key 1.4、新增/修改元素 1.5、删除元素 1.6、遍历…...
Nginx 运维开发高频面试题详解
一、基础核心问题 原文链接:https://blog.csdn.net/weixin_51146329/article/details/142963853 1、什么是Nginx? Nginx 是一个高性能的 HTTP 和反向代理服务器,它以轻量级和高并发处理能力而闻名。Nginx 的反向代理功能允许它作为前端服务…...
下载OpenJDK
由于Oracle需要付费,并且之前我在寻找openJDK的时候,我不知道网址,并且也不知道在这个openjdk这个网址里点击哪个模块进行下载。最近我在看虚拟机相关的书籍的时候,找到了相关的网址。 注意:下面的下载都是基于可以科…...
Web3.js详解
Web1&Web2&Web3 以下是Web1、Web2和Web3的详细介绍,以及一个对比表格: Web1 定义:Web1指的是有着固定内容的非许可的开源网络。特点:在Web1时代,网站内容主要由网站管理员或创建者提供,用户只能…...
学习串行通信
本文来源: [8-1] 串口通信_哔哩哔哩_bilibili 智谱清言 ------------ 串口(Serial Port): 串口是一种应用非常广泛的通讯接口,串口成本低,容易使用,通信线路简单,可实现两个设…...
【leetcode强化练习·二叉树】同时运用两种思维解题
本文参考labuladong算法笔记[【强化练习】同时运用两种思维解题 | labuladong 的算法笔记] 有的题目可以同时用「遍历」和「分解问题」两种思路来解,你可以利用这些题目训练自己的思维。 559. N 叉树的最大深度 | 力扣 | LeetCode | 给定一个 N 叉树,…...
Rank-analysis-1.2——一款基于LCU API的排位分析工具,大四学生独立开发
LOL Rank Record Analysis:一款基于LCU API的排位分析工具,大四学生独立开发! 大家好!我是河南科技学院的大四学生,今天给大家分享一个我自己开发的软件——LOL Rank Record Analysis。这是一个基于 Riot 提供的 LCU …...
什么是门控循环单元?
一、概念 门控循环单元(Gated Recurrent Unit,GRU)是一种改进的循环神经网络(RNN),由Cho等人在2014年提出。GRU是LSTM的简化版本,通过减少门的数量和简化结构,保留了LSTM的长时间依赖…...
Google Chrome-便携增强版[解压即用]
Google Chrome-便携增强版 链接:https://pan.xunlei.com/s/VOI0OyrhUx3biEbFgJyLl-Z8A1?pwdf5qa# a 特点描述 √ 无升级、便携式、绿色免安装,即可以覆盖更新又能解压使用! √ 此增强版,支持右键解压使用 √ 加入Chrome增强…...
智慧园区综合管理系统如何实现多个维度的高效管理与安全风险控制
内容概要 在当前快速发展的城市环境中,智慧园区综合管理系统正在成为各类园区管理的重要工具,无论是工业园、产业园、物流园,还是写字楼与公寓,都在积极寻求如何提升管理效率和保障安全。通过快鲸智慧园区管理系统,用…...
【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙
目录 1. 梯度基本计算 2. 控制梯度计算 3. 梯度计算注意 4. 小节 个人主页:Icomi 专栏地址:PyTorch入门 在深度学习蓬勃发展的当下,PyTorch 是不可或缺的工具。它作为强大的深度学习框架,为构建和训练神经网络提供了高效且灵活…...
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(协议层封装)
目录 协议层设计,以IIC为例子 关于软硬件IIC 设计的一些原则 完成协议层的抽象 刨析我们的原理 如何完成我们的抽象 插入几个C语言小技巧 完成软件IIC通信 开始我们的IIC通信 结束我们的IIC通信 发送一个字节 (重要)完成命令传递和…...
Mac M1 源码安装FFmpeg,开启enable-gpl 和 lib x264
1、第一步:下载并安装minicoda curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.shsh Miniconda3-latest-MacOSX-arm64.sh2、第二步:安装必要的依赖 conda install -c conda-forge gcc make nasm yasm3、第三步ÿ…...
【Quest开发】手柄单手抓握和双手抓握物体切换
V72更新以后非常智能哈,配置物体简单多了。 选择需要被抓取的物体鼠标右键单击它,点Add Grab Interaction,按它要求的配置就行 配好以后长这样 把这个选项取消勾选就能切换成双手抓一个物体了,不需要像以前一样用各种grabTransfo…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
