CSS预处理器对比:Sass、Less与Stylus如何选择
引言
CSS预处理器已成为现代前端开发的标准工具,它们通过添加编程特性来增强纯CSS的功能,使样式表更加模块化、可维护且高效。在众多预处理器中,Sass、Less和Stylus是三个最流行的选择,它们各自拥有独特的语法和功能特点。本文将深入比较这三种预处理器,通过详细的代码示例和实际应用场景,帮助你根据项目需求选择最适合的工具。
1. 概述比较
在深入代码细节前,先看一下三种预处理器的基本情况:
特性 | Sass | Less | Stylus |
---|---|---|---|
诞生时间 | 2006年 | 2009年 | 2010年 |
语法风格 | 两种语法:.scss和.sass | 类CSS语法 | 灵活语法,可省略大部分符号 |
开发语言 | 最初Ruby,现在Dart/JS | JavaScript | JavaScript |
学习曲线 | 中等 | 较低 | 较高 |
社区生态 | 非常庞大 | 庞大 | 相对较小 |
框架集成 | 广泛支持 | 广泛支持 | 有限支持 |
2. 语法与基本特性对比
2.1 变量定义
Sass
// Sass变量使用$符号
$primary-color: #333;
$secondary-color: #777;
$font-stack: Helvetica, sans-serif;body {color: $primary-color;font-family: $font-stack;
}// Sass的变量支持作用域
.container {$local-width: 100%;width: $local-width;
}
Less
// Less变量使用@符号
@primary-color: #333;
@secondary-color: #777;
@font-stack: Helvetica, sans-serif;body {color: @primary-color;font-family: @font-stack;
}// Less的变量也支持作用域
.container {@local-width: 100%;width: @local-width;
}
Stylus
// Stylus变量不需要特殊符号,但也可以使用$
primary-color = #333
secondary-color = #777
font-stack = Helvetica, sans-serifbodycolor primary-colorfont-family font-stack// Stylus的变量也支持作用域
.containerlocal-width = 100%width local-width
2.2 嵌套规则
Sass
// Sass嵌套规则
nav {background-color: #fff;ul {margin: 0;padding: 0;list-style: none;li {display: inline-block;a {display: block;padding: 6px 12px;text-decoration: none;&:hover {background-color: #eee;}}}}
}
Less
// Less嵌套规则
nav {background-color: #fff;ul {margin: 0;padding: 0;list-style: none;li {display: inline-block;a {display: block;padding: 6px 12px;text-decoration: none;&:hover {background-color: #eee;}}}}
}
Stylus
// Stylus嵌套规则
navbackground-color #fffulmargin 0padding 0list-style nonelidisplay inline-blockadisplay blockpadding 6px 12pxtext-decoration none&:hoverbackground-color #eee
2.3 混合(Mixins)
Sass
// Sass混合定义
@mixin border-radius($radius) {-webkit-border-radius: $radius;-moz-border-radius: $radius;-ms-border-radius: $radius;border-radius: $radius;
}// 使用混合
.box {@include border-radius(10px);
}// 带参数默认值的混合
@mixin box-shadow($x: 0, $y: 0, $blur: 1px, $color: #000) {-webkit-box-shadow: $x $y $blur $color;-moz-box-shadow: $x $y $blur $color;box-shadow: $x $y $blur $color;
}.panel {@include box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5));
}// 可变参数混合
@mixin transition($transitions...) {-webkit-transition: $transitions;-moz-transition: $transitions;transition: $transitions;
}.fade {@include transition(color 0.3s ease-in, background-color 0.5s ease-out);
}
Less
// Less混合定义
.border-radius(@radius) {-webkit-border-radius: @radius;-moz-border-radius: @radius;-ms-border-radius: @radius;border-radius: @radius;
}// 使用混合
.box {.border-radius(10px);
}// 带参数默认值的混合
.box-shadow(@x: 0, @y: 0, @blur: 1px, @color: #000) {-webkit-box-shadow: @x @y @blur @color;-moz-box-shadow: @x @y @blur @color;box-shadow: @x @y @blur @color;
}.panel {.box-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5));
}// 可变参数混合
.transition(@transitions...) {-webkit-transition: @transitions;-moz-transition: @transitions;transition: @transitions;
}.fade {.transition(color 0.3s ease-in, background-color 0.5s ease-out);
}
Stylus
// Stylus混合定义
border-radius(radius)-webkit-border-radius radius-moz-border-radius radius-ms-border-radius radiusborder-radius radius// 使用混合
.boxborder-radius(10px)// 带参数默认值的混合
box-shadow(x = 0, y = 0, blur = 1px, color = #000)-webkit-box-shadow x y blur color-moz-box-shadow x y blur colorbox-shadow x y blur color.panelbox-shadow(2px, 2px, 5px, rgba(0, 0, 0, 0.5))// 可变参数混合
transition(args...)-webkit-transition args-moz-transition argstransition args.fadetransition(color 0.3s ease-in, background-color 0.5s ease-out)
3. 高级特性对比
3.1 继承(Extend)
Sass
// Sass继承
.message {border: 1px solid #ccc;padding: 10px;color: #333;
}.success {@extend .message;border-color: green;
}.error {@extend .message;border-color: red;
}// 占位选择器(Placeholder Selectors)
%btn-base {display: inline-block;padding: 6px 12px;text-align: center;border-radius: 4px;
}.btn-primary {@extend %btn-base;background-color: #007bff;color: white;
}.btn-secondary {@extend %btn-base;background-color: #6c757d;color: white;
}
Less
// Less继承
.message {border: 1px solid #ccc;padding: 10px;color: #333;
}.success {&:extend(.message);border-color: green;
}.error {&:extend(.message);border-color: red;
}// Less中没有占位选择器的概念,但可以使用混合实现类似功能
.btn-base() {display: inline-block;padding: 6px 12px;text-align: center;border-radius: 4px;
}.btn-primary {.btn-base();background-color: #007bff;color: white;
}.btn-secondary {.btn-base();background-color: #6c757d;color: white;
}
Stylus
// Stylus继承
.messageborder 1px solid #cccpadding 10pxcolor #333.success@extend .messageborder-color green.error@extend .messageborder-color red// Stylus也支持占位符选择器
$btn-basedisplay inline-blockpadding 6px 12pxtext-align centerborder-radius 4px.btn-primary@extend $btn-basebackground-color #007bffcolor white.btn-secondary@extend $btn-basebackground-color #6c757dcolor white
3.2 函数和运算
Sass
// Sass函数和运算
$base-size: 16px;// 自定义函数
@function calculate-width($col-count, $total-cols: 12) {@return percentage($col-count / $total-cols);
}.container {// 数学运算padding: $base-size / 2;// 函数调用width: calculate-width(8);
}// 颜色函数
.button {background-color: #3498db;&:hover {// 颜色变暗background-color: darken(#3498db, 15%);}&.light {// 颜色变亮background-color: lighten(#3498db, 15%);}&.transparent {// 透明度调整background-color: rgba(#3498db, 0.5);}
}// 字符串函数
$font-path: 'assets/fonts/';
$font-name: 'opensans';
$font-file: $font-path + $font-name + '.woff';@font-face {font-family: 'Open Sans';src: url(#{$font-file});
}
Less
// Less函数和运算
@base-size: 16px;// 自定义函数(通过混合实现)
.calculate-width(@col-count, @total-cols: 12) {@result: percentage(@col-count / @total-cols);// Less混合返回值& { width: @result; }
}.container {// 数学运算padding: @base-size / 2;// 函数调用.calculate-width(8);
}// 颜色函数
.button {background-color: #3498db;&:hover {// 颜色变暗background-color: darken(#3498db, 15%);}&.light {// 颜色变亮background-color: lighten(#3498db, 15%);}&.transparent {// 透明度调整background-color: fade(#3498db, 50%);}
}// 字符串函数
@font-path: 'assets/fonts/';
@font-name: 'opensans';
@font-file: @font-path + @font-name + '.woff';@font-face {font-family: 'Open Sans';src: url(@{font-file});
}
Stylus
// Stylus函数和运算
base-size = 16px// 自定义函数
calculate-width(col-count, total-cols = 12)return percentage(col-count / total-cols).container// 数学运算padding base-size / 2// 函数调用width calculate-width(8)// 颜色函数
.buttonbackground-color #3498db&:hover// 颜色变暗background-color darken(#3498db, 15%)&.light// 颜色变亮background-color lighten(#3498db, 15%)&.transparent// 透明度调整background-color rgba(#3498db, 0.5)// 字符串函数
font-path = 'assets/fonts/'
font-name = 'opensans'
font-file = font-path + font-name + '.woff'@font-facefont-family 'Open Sans'src url(font-file)
3.3 条件语句和循环
Sass
// Sass条件语句
$theme: 'dark';.container {@if $theme == 'light' {background-color: #fff;color: #333;} @else if $theme == 'dark' {background-color: #333;color: #fff;} @else {background-color: #f5f5f5;color: #555;}
}// Sass循环
// for循环
@for $i from 1 through 5 {.col-#{$i} {width: 20% * $i;}
}// each循环(遍历列表)
$social-colors: (facebook: #3b5998,twitter: #1da1f2,instagram: #e1306c
);@each $platform, $color in $social-colors {.btn-#{$platform} {background-color: $color;color: white;}
}// while循环
$i: 1;
$max: 5;@while $i <= $max {.mt-#{$i} {margin-top: $i * 0.25rem;}$i: $i + 1;
}
Less
// Less条件语句(通过混合实现)
@theme: 'dark';.theme-styles() when (@theme = 'light') {background-color: #fff;color: #333;
}.theme-styles() when (@theme = 'dark') {background-color: #333;color: #fff;
}.theme-styles() when (default()) {background-color: #f5f5f5;color: #555;
}.container {.theme-styles();
}// Less循环
// for循环 (使用循环混合)
.generate-columns(@i: 1) when (@i <= 5) {.col-@{i} {width: 20% * @i;}.generate-columns(@i + 1);
}
.generate-columns();// each循环
@social-colors: {facebook: #3b5998;twitter: #1da1f2;instagram: #e1306c;
}.generate-social-btns(@i: 1) when (@i <= length(@social-colors)) {@platform: extract(keys(@social-colors), @i);@color: extract(values(@social-colors), @i);.btn-@{platform} {background-color: @color;color: white;}.generate-social-btns(@i + 1);
}
.generate-social-btns();// while循环 (使用递归混合)
.generate-margins(@i: 1) when (@i <= 5) {.mt-@{i} {margin-top: @i * 0.25rem;}.generate-margins(@i + 1);
}
.generate-margins();
Stylus
// Stylus条件语句
theme = 'dark'.containerif theme == 'light'background-color #fffcolor #333else if theme == 'dark'background-color #333color #fffelsebackground-color #f5f5f5color #555// Stylus循环
// for循环
for i in (1..5).col-{i}width 20% * i// each循环
social-colors = {facebook: #3b5998,twitter: #1da1f2,instagram: #e1306c
}for platform, color in social-colors.btn-{platform}background-color colorcolor white// while循环
i = 1
max = 5while i <= max.mt-{i}margin-top i * 0.25remi = i + 1
4. 实际应用场景
4.1 响应式网格系统
Sass
// Sass实现响应式网格系统
$grid-columns: 12;
$grid-gutter: 30px;
$breakpoints: (xs: 0,sm: 576px,md: 768px,lg: 992px,xl: 1200px
);.container {width: 100%;padding-right: $grid-gutter / 2;padding-left: $grid-gutter / 2;margin-right: auto;margin-left: auto;@each $breakpoint, $width in $breakpoints {@if $width > 0 {@media (min-width: $width) {max-width: $width;}}}
}.row {display: flex;flex-wrap: wrap;margin-right: -$grid-gutter / 2;margin-left: -$grid-gutter / 2;
}@each $breakpoint, $width in $breakpoints {$infix: if($breakpoint == 'xs', '', '-#{$breakpoint}');@media (min-width: $width) {@for $i from 1 through $grid-columns {.col#{$infix}-#{$i} {flex: 0 0 percentage($i / $grid-columns);max-width: percentage($i / $grid-columns);padding-right: $grid-gutter / 2;padding-left: $grid-gutter / 2;}}}
}
Less
// Less实现响应式网格系统
@grid-columns: 12;
@grid-gutter: 30px;
@breakpoint-xs: 0;
@breakpoint-sm: 576px;
@breakpoint-md: 768px;
@breakpoint-lg: 992px;
@breakpoint-xl: 1200px;.container {width: 100%;padding-right: @grid-gutter / 2;padding-left: @grid-gutter / 2;margin-right: auto;margin-left: auto;@media (min-width: @breakpoint-sm) {max-width: @breakpoint-sm;}@media (min-width: @breakpoint-md) {max-width: @breakpoint-md;}@media (min-width: @breakpoint-lg) {max-width: @breakpoint-lg;}@media (min-width: @breakpoint-xl) {max-width: @breakpoint-xl;}
}.row {display: flex;flex-wrap: wrap;margin-right: -@grid-gutter / 2;margin-left: -@grid-gutter / 2;
}.make-grid-columns(@prefix, @grid-columns) {.col-loop(@i) when (@i <= @grid-columns) {.col@{prefix}-@{i} {flex: 0 0 percentage(@i / @grid-columns);max-width: percentage(@i / @grid-columns);padding-right: @grid-gutter / 2;padding-left: @grid-gutter / 2;}.col-loop(@i + 1);}.col-loop(1);
}// XS breakpoint
.make-grid-columns('', @grid-columns);// SM breakpoint
@media (min-width: @breakpoint-sm) {.make-grid-columns('-sm', @grid-columns);
}// MD breakpoint
@media (min-width: @breakpoint-md) {.make-grid-columns('-md', @grid-columns);
}// LG breakpoint
@media (min-width: @breakpoint-lg) {.make-grid-columns('-lg', @grid-columns);
}// XL breakpoint
@media (min-width: @breakpoint-xl) {.make-grid-columns('-xl', @grid-columns);
}
Stylus
// Stylus实现响应式网格系统
grid-columns = 12
grid-gutter = 30px
breakpoints = {xs: 0,sm: 576px,md: 768px,lg: 992px,xl: 1200px
}.containerwidth 100%padding-right grid-gutter / 2padding-left grid-gutter / 2margin-right automargin-left autofor breakpoint, width in breakpointsif width > 0@media (min-width: width)max-width width.rowdisplay flexflex-wrap wrapmargin-right -(grid-gutter / 2)margin-left -(grid-gutter / 2)for breakpoint, width in breakpointsinfix = breakpoint == 'xs' ? '' : '-' + breakpoint@media (min-width: width)for i in (1..grid-columns).col{infix}-{i}flex 0 0 percentage(i / grid-columns)max-width percentage(i / grid-columns)padding-right grid-gutter / 2padding-left grid-gutter / 2
4.2 主题系统
Sass
// Sass主题系统
// _variables.scss
$themes: (light: (bg-color: #ffffff,text-color: #333333,primary-color: #4285f4,secondary-color: #fbbc05,border-color: #e0e0e0),dark: (bg-color: #121212,text-color: #f5f5f5,primary-color: #8ab4f8,secondary-color: #ffd04b,border-color: #333333)
);// _mixins.scss
@mixin themed() {@each $theme, $map in $themes {.theme-#{$theme} & {$theme-map: () !global;@each $key, $value in $map {$theme-map: map-merge($theme-map, ($key: $value)) !global;}@content;$theme-map: null !global;}}
}@function t($key) {@return map-get($theme-map, $key);
}// main.scss
@import 'variables';
@import 'mixins';body {margin: 0;font-family: Arial, sans-serif;transition: all 0.3s ease;
}.card {@include themed() {background-color: t('bg-color');color: t('text-color');border: 1px solid t('border-color');}border-radius: 8px;padding: 20px;margin: 10px;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}.button {@include themed() {background-color: t('primary-color');color: t('bg-color');border: 1px solid t('primary-color');&:hover {background-color: darken(t('primary-color'), 10%);}}padding: 10px 15px;border-radius: 4px;cursor: pointer;transition: all 0.2s ease;
}// 使用主题
.theme-light {// light theme is active
}.theme-dark {// dark theme is active
}
Less
// Less主题系统
// variables.less
@themes: {light: {bg-color: #ffffff;text-color: #333333;primary-color: #4285f4;secondary-color: #fbbc05;border-color: #e0e0e0;};dark: {bg-color: #121212;text-color: #f5f5f5;primary-color: #8ab4f8;secondary-color: #ffd04b;border-color: #333333;};
};// mixins.less
.themed-styles(@rules) {each(@themes, {.theme-@{key} & {@theme-props: @value;@rules();}});
}.t(@property) {@result: @theme-props[@@property];
}// main.less
@import 'variables.less';
@import 'mixins.less';body {margin: 0;font-family: Arial, sans-serif;transition: all 0.3s ease;
}.card {.themed-styles({background-color: .t(bg-color);color: .t(text-color);border: 1px solid .t(border-color);});border-radius: 8px;padding: 20px;margin: 10px;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}.button {.themed-styles({background-color: .t(primary-color);color: .t(bg-color);border: 1px solid .t(primary-color);&:hover {background-color: darken(.t(primary-color), 10%);}});padding: 10px 15px;border-radius: 4px;cursor: pointer;transition: all 0.2s ease;
}// 使用主题
.theme-light {// light theme is active
}.theme-dark {// dark theme is active
}
Stylus
// Stylus主题系统
// variables.styl
themes = {light: {bg-color: #ffffff,text-color: #333333,primary-color: #4285f4,secondary-color: #fbbc05,border-color: #e0e0e0},dark: {bg-color: #121212,text-color: #f5f5f5,primary-color: #8ab4f8,secondary-color: #ffd04b,border-color: #333333}
}// mixins.styl
themed()for theme, props in themes.theme-{theme} &theme-map = props{block}t(key)return theme-map[key]// main.styl
@import 'variables'
@import 'mixins'bodymargin 0font-family Arial, sans-seriftransition all 0.3s ease.card+themed()background-color t('bg-color')color t('text-color')border 1px solid t('border-color')border-radius 8pxpadding 20pxmargin 10pxbox-shadow 0 2px 5px rgba(0, 0, 0, 0.1).button+themed()background-color t('primary-color')color t('bg-color')border 1px solid t('primary-color')&:hoverbackground-color darken(t('primary-color'), 10%)padding 10px 15pxborder-radius 4pxcursor pointertransition all 0.2s ease// 使用主题
.theme-light// light theme is active.theme-dark// dark theme is active
5. 各预处理器的优缺点分析
5.1 Sass
优点:
- 功能最为强大完整,拥有最丰富的功能集
- 有两种语法选择:缩进式的
.sass
和兼容CSS的.scss
- 社区最大,资源最丰富,有大量现成的库和框架(如Bootstrap、Foundation等)
- 最成熟的变量、函数和模块系统
- 出色的错误报告和调试工具
- 可扩展性强,支持自定义函数和插件
缺点:
- 相比Less,安装和配置稍微复杂一些
- 完整学习所有功能需要较长时间
- 编译速度相对较慢,尤其是大型项目
5.2 Less
优点:
- 语法最接近CSS,学习曲线低
- 基于JavaScript,可以在浏览器端运行
- 安装配置简单,易于集成
- 与JavaScript结合紧密,便于Web开发者上手
- 编译速度快,适合中小型项目
缺点:
- 功能不如Sass丰富,特别是在高级编程功能方面
- 没有真正的函数功能,只能通过混合模拟
- 运行时错误处理不如Sass完善
- 扩展性相对较弱
5.3 Stylus
优点:
- 语法最为灵活,几乎所有标点和括号都是可选的
- 具有强大的编程能力,接近JavaScript的表达能力
- 内置函数库丰富
- 极简主义风格,代码最为简洁
- 性能优秀,编译速度快
缺点:
- 社区和生态系统相对较小
- 灵活的语法可能导致代码风格不统一
- 学习曲线较陡峭,特别是对于CSS新手
- 文档和资源不如Sass和Less丰富
- 主流框架和库的支持较少
6. 实际项目选择建议
根据上述对比和分析,以下是针对不同场景的CSS预处理器选择建议:
6.1 何时选择Sass
适合以下场景:
- 大型复杂项目,需要完整的功能集
- 团队已有Sass经验,或者项目与使用Sass的库有集成需求
- 需要使用高级功能,如模块系统、占位选择器等
- 使用Ruby on Rails、Angular等已集成Sass的框架
- 长期维护的企业级应用,需要良好的扩展性和模块化
推荐使用Sass的情况:
// 如果你需要使用以下功能,推荐Sass
// 1. 模块化系统
@use 'buttons';
@use 'forms';// 2. 占位选择器
%shared-style {border: 1px solid #ccc;padding: 10px;
}.button {@extend %shared-style;// 更多样式...
}// 3. 强大的内置函数
$colors: (primary: #3498db,secondary: #2ecc71
);@function color($name) {@return map-get($colors, $name);
}.element {color: color(primary);
}
6.2 何时选择Less
适合以下场景:
- 中小型项目,需要快速上手
- 团队主要由Web前端开发者组成,熟悉JavaScript
- 项目与使用Less的库集成(如早期的Bootstrap)
- 希望配置简单,构建速度快
- 项目需要在浏览器中直接编译CSS
推荐使用Less的情况:
// 如果你需要以下功能,推荐Less
// 1. 浏览器端编译
<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js"></script>// 2. 简单的变量和混合
@main-color: #3498db;.button-style {background-color: @main-color;border-radius: 4px;
}.primary-button {.button-style();color: white;
}// 3. 与JavaScript结合紧密
@link-color: #428bca;
@link-color-hover: darken(@link-color, 15%);
6.3 何时选择Stylus
适合以下场景:
- 追求极简语法和代码简洁
- 有Node.js开发背景的团队
- 需要高性能编译
- 小型或实验性项目
- 喜欢灵活的编程风格
推荐使用Stylus的情况:
// 如果你喜欢以下特性,推荐Stylus
// 1. 极简语法
bodyfont 14px/1.5 Arial, sans-serifbackground-color #f5f5f5// 2. 强大的内置函数和表达式
sum(a, b)a + bborder-radius()-webkit-border-radius arguments-moz-border-radius argumentsborder-radius argumentsboxwidth sum(10px, 20px)border-radius 5px// 3. 隐式混合调用
@import 'mixins'.elementbutton-style() // 无需使用特殊符号调用混合
7. 总结
每种CSS预处理器都有其独特的优势和使用场景:
Sass 是功能最完整、社区最庞大的选择,适合大型项目和长期维护的应用。它提供了强大的模块系统、函数和混合功能,同时支持两种语法格式。虽然学习曲线较陡,但其强大的功能和生态系统使其成为当前最流行的CSS预处理器。
Less 以其接近原生CSS的语法和简单的学习曲线脱颖而出,非常适合中小型项目或需要快速上手的团队。它基于JavaScript,可以在浏览器端运行,配置简单,构建速度快。
Stylus 提供了最灵活的语法和强大的编程能力,适合追求代码简洁性和表达力的开发者。它的语法几乎完全自由,提供了丰富的内置函数,但社区相对较小,资源相对较少。
最终的选择应该基于以下因素:
- 项目规模和复杂度
- 团队经验和技术栈
- 与现有框架或库的兼容性
- 性能需求
- 开发效率和维护性考虑
无论选择哪种预处理器,它们都能显著提高CSS的可维护性、可重用性和编写效率,是现代前端开发不可或缺的工具。
相关文章:
CSS预处理器对比:Sass、Less与Stylus如何选择
引言 CSS预处理器已成为现代前端开发的标准工具,它们通过添加编程特性来增强纯CSS的功能,使样式表更加模块化、可维护且高效。在众多预处理器中,Sass、Less和Stylus是三个最流行的选择,它们各自拥有独特的语法和功能特点。本文将深…...
Vue3集成sass
安装依赖 pnpm add -D sass-embedded配置全局变量 新建文件 src/styles/variables.scss配置Vite 修改 vite.config.ts variables.scss $base-color: bluevite.config.ts // https://vite.dev/config/ export default defineConfig({plugins: [vue(),],resolve: {alias: {:…...
超越Dify工作流:如何通过修改QwenAgent的Function Call及ReAct方法实现对日期时间的高效意图识别
在构建复杂的AI应用时,意图识别是一个至关重要的环节。传统上,许多开发者会使用Dify工作流来完成这一任务,但在处理复杂意图时,这种方法往往需要大模型进行多级反复识别,从而带来较高的时间成本。 本文将介绍如何通过修改QwenAgent框架中的FnCallAgent和ReActChat类,实现…...
Lua 第8部分 补充知识
8.1 局部变量和代码块 Lua 语言中的变量在默认情况下是全局变量 ,所有的局部变量在使用前必须声明 。 与全局变量不同,局部变量的生效范围仅限于声明它的代码块。一个代码块( block )是一个控制结构的主体,或是一个函…...
Lua 第7部分 输入输出
由于 Lua 语言强调可移植性和嵌入性 , 所以 Lua 语言本身并没有提供太多与外部交互的机制 。 在真实的 Lua 程序中,从图形、数据库到网络的访问等大多数 I/O 操作,要么由宿主程序实现,要么通过不包括在发行版中的外部库实现。 单就…...
Java 中 == 和 equals() 的区别
1. 运算符 是 Java 中的比较运算符,用于比较两个变量的值是否相等,但具体行为取决于变量的类型: 类型 比较的内容基本类型直接比较值是否相等(如 int a 5; int b 5; a b 返回 true)引用类型比较内存地址&#x…...
Redis新节点加入集群会发生什么(面试题)
新加入主节点:会发生槽位数据重新分配迁移, 新加入从节点,会发生主从同步,全量同步和增量同步 当一个新节点加入 Redis 集群时,会触发一系列操作以确保集群的稳定性和数据的一致性。以下是新节点加入 Redis 集群时的详…...
dmncdm达梦新云缓存数据库主从集群安装部署详细步骤说明
dmncdm达梦新云缓存数据库主从集群安装部署详细步骤说明 1 环境介绍2 安装部署dmncdm2.1 196部署cdm环境2.2 197部署cdm环境2.3 190部署cdm环境 3 主备集群/主从集群配置4 部署主备集群/主从集群5 部署日志6 更多达梦数据库全方位指南:安装 优化 与实战教程 1 环境介绍 cpu x8…...
docker容器,mysql的日志文件怎么清理
访问问题 你的问题是因为在当前路径 /home/ictrek/data/ragflow-mysql 下没有名为 data 的子目录。以下是详细分析和解决方法: 错误原因 路径不存在 当前目录 /home/ictrek/data/ragflow-mysql 下没有名为 data 的子目录,执行 cd data/ 时会报错 No suc…...
kafka auto.offset.reset详解
在 Kafka 中,auto.offset.reset latest 的含义及行为如下: 1. 核心定义 当消费者组首次启动或无法找到有效的 offset(例如 offset 过期、被删除或从未提交)时,消费者会从分区的最新位置…...
设备制造行业如何避免项目管理混乱?
项目常因进度延误、成本超支或部门协作不畅而陷入混乱? 这不仅拖累项目交付,还可能损害客户信任和企业利润。设备制造行业的项目管理复杂多变,从需求获取到生产交付再到售后运维,每一个环节都可能成为效率的瓶颈。 如何破解这一…...
kubernetes》》k8s》》删除命名空间
使用 kubectl delete ns 命名空间 --force --grace-period0 如果还删除不掉 需要 kubectl get namespace 命名空间 -o json > x.json vim x.json kubectl replace --raw “/api/v1/namespaces/命名空间/finalize” -f ./x.json...
【深度学习新浪潮】新视角生成的研究进展调研报告(2025年4月)
新视角生成(Novel View Synthesis)是计算机视觉与图形学领域的核心技术,旨在从单张或稀疏图像中生成任意视角的高保真图像,突破传统多视角数据的限制,实现对三维场景的自由探索。作为计算机视觉与图形学的交叉领域,近新视角生成年来在算法创新、应用落地和工具生态上均取…...
55、Spring Boot 详细讲义(十一 项目实战)springboot应用的登录功能和权限认证
项目文档:springboot应用的登录功能和权限认证 一、项目概述 1. 项目简介 本项目是在一个基于Spring Boot的Web应用中实现登录功能和权限认证。要求实现登录功能,用户登录成功以后,会给前台返回当前登录用户可以访问的权限菜单,比如超级管理员可以访问所有权限,产品管理…...
react 父子组件通信 子 直接到父, 父 forwardref子
React核心概念:单向数据流(Unidirectional Data Flow) React 中数据的流动像瀑布一样,只能从上层组件(父组件)流向下层组件(子组件)。 子组件无法直接反向修改父组件的数据&#x…...
基于TCP的协议
目录 TCP 基于TCP的应用层协议: TCP的工作方式 TCP TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。它为应用层提供了一个可靠的端到端的数据传输服务。再TCP/IP模型中,TCP位于传输层,负责再…...
性能比拼: Go vs Java
本内容是对知名性能评测博主 Anton Putra Go (Golang) vs Java: Performance Benchmark 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 在本视频中,我们将比较 Go 和 Java。 我们将基于 Golang 的 Fiber 框架和 Java 的 Spring Boot 创建几个简单的应用…...
【Spring】单例作用域下多次访问同一个接口
在Spring框架中,Controller和Service的Bean默认都是单例(Singleton)的。在多个请求同时访问Controller时,Service的Bean调用情况如下: 1. 核心机制 单例Bean:Spring容器为每个Bean定义(如Serv…...
数据库介绍
1、什么是数据库 数据库是一个“广义的概念" 1. 表示一门学科 2. 表示一类软件,管理数据的软件 3. 表示某一个具体的数据库软件 4. 表示部署了某个数据库软件的主机(电脑) 本专栏介绍的是具体的数据库软件:MySQL 数据库软件的主要功能是对数据的增删…...
Spring XML 配置
Spring XML 配置是 Spring Framework 的传统配置方式,通过 XML 文件定义 Bean、依赖注入、AOP 等核心功能。以下是详细的 Spring XML 配置解析: 一、基础配置 1. XML 配置文件结构 <?xml version"1.0" encoding"UTF-8"?> …...
AI数字人:品牌营销的新宠与增长密码(6/10)
摘要:AI数字人凭借低成本、高可控性与强互动性等优势,正成为品牌营销新宠。通过技术驱动,AI数字人从虚拟形象发展为智能交互的数字化身,广泛应用于直播、客服、内容生产等营销场景,助力品牌提升营销效果与用户互动体验…...
CentOS笔记本合上盖子不休眠
通过修改 /etc/systemd/logind.conf 文件中的 HandleLidSwitch 和 HandleLidSwitchDocked 设置为 ignore,可以实现合上笔记本盖子时不休眠的效果。如果有其他电源管理工具或桌面环境的设置干扰,也需要一并调整。 // 切换到root用户 su root// logind.co…...
Vue.js 之 `v-for` 命令详解
Vue.js 之 v-for 命令详解 在 Vue.js 中,v-for 是一个非常强大的指令,用于遍历数组或对象中的数据,并渲染相应的 DOM 元素。无论是在列表展示、表单生成还是动态组件加载中,v-for 都发挥着重要作用。本文将详细介绍 v-for 的用法…...
Linux命令-pidstat
pidstat命令是一个用于监控系统中各个进程活动的性能监控工具。它能够实时输出每个进程的 CPU、内存、I/O 等关键性能指标。以下是关于 pidstat 命令的详细介绍: 语法 pidstat [选项] [时间间隔] [次数]常用选项 -h 或 --help :显示帮助信息。 -v &…...
map和set
1.序列式容器和关联式容器 在认识map和set之前,关于容器,有两个重要的分类 序列式容器关联式容器 序列式容器:按照元素插入的顺序保存数据,关注元素的顺序和位置,因为逻辑结构为线性序列的数据结构,两个位…...
CentOS 6.9 安装 Zabbix 3.0 详细教程
一、引言 在 Linux 环境下,有许多实用的系统监控软件,如 Nagios、Cacti、Zabbix、Monit等。这些开源软件能帮助我们更好地管理机器,及时发现问题并警告系统维护人员。今天我们将重点研究 Zabbix,使用它的目的是为了更好地监控MySQ…...
通俗的理解TCP的三次握手四次挥手
前言 本文是博主根据自身理解,尽量用最通俗的形式解释TCP的三次握手四次挥手。 一、三次握手:为什么不是两次或四次? 1. 三次握手过程 SYN:客户端发送SYN1, seqx(我要连接)SYNACK:服务器回复…...
【Python进阶】正则表达式实战指南:从基础到高阶应用
目录 前言技术背景与价值当前技术痛点解决方案概述目标读者说明 一、技术原理剖析核心概念图解核心作用讲解关键技术模块说明技术选型对比 二、实战演示环境配置要求核心代码实现案例1:邮箱格式验证案例2:提取电话号码案例3:替换敏感信息 运行…...
linux下内存地址数学运算
如下代码计算地址并16字节对齐: char* buffer (char*)malloc(a3 0x1000);unsigned long long tmp (((unsigned long long)buffer 0x10) & 0xffffffffffffff00);char* buf (char*)tmp;假如把地址当作整数,加减程序运算,直接转换是不行…...
考研单词笔记 2025.04.22
abuse v/n滥用,妄用,虐待,伤害 adopt v采用,采纳,收养,领养,正式通过,批准 apply v应用,运用,申请,适用,有效 deploy v有效利用&am…...
JVM虚拟机-类加载器、双亲委派模型、类装载的执行过程
一、什么是类加载器,类加载器有哪些 我们目前要讲的就是类加载子系统,主要作用是将java源码编译为class字节码文件后装载到运行时数据区,运行时数据区就可以去分配内存再通过执行引擎来执行java代码。 启动类加载器(也称引导类加载器)&…...
神经网络的 “成长密码”:正向传播与反向传播深度解析(四)
引言 在神经网络的神秘世界里,正向传播和反向传播是驱动模型学习和进化的核心机制。它们如同神经网络的 “左右脑”,正向传播负责信息的前向流动与初步处理,反向传播则通过优化权重参数来提升模型性能,二者相辅相成,共…...
激活函数:神经网络的 “魔法开关”,开启智能之门(三)
引言 在神经网络的复杂架构中,激活函数扮演着至关重要的角色,堪称神经网络的 “魔法开关”。它赋予了神经网络强大的能力,让其能够处理各种复杂的任务。本文将深入剖析激活函数的重要性、引入原因、常见类型以及选择策略,并针对面…...
服装印花/印烫环节计算机视觉应用设计方案
服装印花/印烫环节计算机视觉应用设计方案 一、引言 随着消费者对服装个性化、多样化需求的增加,服装印花/印烫环节作为服装生产中的重要一环,其质量和效率直接影响到产品的竞争力和市场占有率。传统的服装印花/印烫环节存在以下痛点: 人为…...
vue3:十一、主页面布局(修改左侧导航条的样式)
一、样式 1、初始样式 2、 左侧导航栏搭建完成样式 二、实现 1、设置左侧导航栏底色 (1)去掉顶部和左侧导航栏的底色 初始页面效果 顶部与左侧底色样式 将代码中与顶部与左侧的样式删掉 移除后页面效果 加入设定背景色 #f4f6f9 加入底色后颜色展示 (2)去除菜单项底色 初…...
Sentinel源码—8.限流算法和设计模式总结二
大纲 1.关于限流的概述 2.高并发下的四大限流算法原理及实现 3.Sentinel使用的设计模式总结 3.Sentinel使用的设计模式总结 (1)责任链模式 (2)监听器模式 (3)适配器模式 (4)模版方法模式 (5)策略模式 (6)观察者模式 (1)责任链模式 一.责任链接口ProcessorSlot 二.责…...
Docker 部署 MySQL 数据库
Docker 部署 MySQL 数据库 基于 Docker 部署 MySQL 数据库一、拉取 MySQL 镜像二、运行 MySQL 容器三、运行命令参数详解四、查看容器运行状态 基于 Docker 部署 MySQL 数据库 一、拉取 MySQL 镜像 在开始之前,请确保你的 Docker 环境已经正确安装并可以正常运行。…...
【Linux运维涉及的基础命令与排查方法大全】
文章目录 前言1、计算机网络常用端口2、Kali Linux中常用的命令3、Kali Linux工具的介绍4、Ubuntu没有网络连接解决方法5、获取路由6、数据库端口 前言 以下介绍计算机常见的端口已经对应的网络协议,Linux中常用命令,以及平时运维中使用的排查网络故障的…...
映射(Mapping)和地址(Address)
Addresses (地址) 以太坊区块链由 _ account _ (账户)组成,你可以把它想象成银行账户。一个帐户的余额是 以太 (在以太坊区块链上使用的币种),你可以和其他帐户之间支付和接受以太币,就像你的银…...
用Java实现简易区块链:从零开始的探索
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 区块链技术作为近年来的热门话题&am…...
Spark-Streaming
Spark-Streaming 一、Spark-Streaming简介 1、Spark-Streaming概述 1.1、Spark-Streaming是什么 Spark Streaming 用于流式数据的处理。Spark Streaming 支持的数据输入源很多,例如:Kafka、Flume、Twitter等,以及和简单的 TCP 套接字等等…...
工程投标k值分析系统(基于微服务实现)
1 需求总括 2 企业管理模块: 新增、删除、修改企业/部门 <...
WebGL 工作原理
WebGL在GPU上的工作基本上分为两部分 第一部分是将顶点(或数据流)转换到裁剪空间坐标 就是将传入的位置坐标,转换为0-1的值,并绘制出来每个顶点的坐标(传入的值)通过顶点着色器计算转换为裁剪空间坐标转换…...
【 React 】重点知识总结 快速上手指南
react 是 facebook 出的一款针对视图层的库。react 使用的是单向数据流的机制 React 官方中文文档 基础 api 和语法 jsx 语法 就是在 js 中插入 html 片段 在 React 中所有的组件都是 function 组件定义 function 定义组件 就是使用 function 定义组件 任何一个 function …...
Docker 部署 Redis 缓存服务
Docker 部署 Redis 缓存服务 基于 Docker 部署 Redis 缓存服务一、拉取 Redis 镜像二、运行 Redis 容器三、运行命令参数详解四、查看容器运行状态 基于 Docker 部署 Redis 缓存服务 一、拉取 Redis 镜像 确保 Docker 环境已正确安装并运行,打开终端执行以下命令拉…...
A2A + MCP:构建实用人工智能系统的超强组合
构建真正有效的连接型人工智能系统的挑战 如果你正在构建人工智能应用,这种情况可能听起来很熟悉: 你需要特定的人工智能能力来解决业务问题。你找到了完成每个单独任务的出色工具。但把所有东西连接在一起却占据了大部分开发时间,还创建了…...
全能 Sui 技术栈,构建 Web3 的未来
本文翻译自:FourPillarsFP,文章仅代表作者观点。 2025 年,SuiNetwork正在以一套全栈区块链策略强势出击,彻底打破加密行业的传统范式。正如 Mysten Labs 联合创始人 Adeniyi Abiodun 所说:“Sui 不只是一条区块链&…...
企业微信私域运营,基于http协议实现SCRM+AI完整解决方案
1、方案介绍 基于企业微信原生功能已实现全场景的能力覆盖,并提供标准化可直接调用的API接口,可以帮助企业轻松实现上层应用的开发及落地,方案采用模拟通信技术可实现PC,手机,ipad三端的同时在线,单服务器…...
【C++】Json-Rpc框架项目介绍(1)
项目介绍 RPC(Remote Procedure Call)即远程过程调用,是一种通过网络从远程计算机程序中请求服务而不需要了解底层网络实现细节的一种 协议 。 RPC(Remote Procedure Call)可以使用多种网络协议进行通信,如…...
数据结构图论基础知识(一)
文章目录 1. 图的基本概念2. 图的一些现实的应用2.1 ABCDE各个城市之间的关系2.2 社交关系 3. 图的存储结构3.1邻接矩阵3.2 邻接矩阵的实现3.3 邻接表 1. 图的基本概念 1. (graph)图由边(edge)和顶点(Vertexÿ…...