月度归档:2023年02月

数据库究竟存0还是null或者”有标准答案

存0的情况

  • 数值型但是需要统计:比如余额,订单总额

存null的情况

  • 外键可以为空:比如admin_user_id)如果为系统操作,可以为null,这时候存0必须取消数据库约束,或者不建外键约束,都不如存null好

存”的情况

  • 非必填且填写的字符串可以为空字符串:比如外国人的middle name,存”可以方便的拼接full name,这个时候如果不需要拼接,你还是可以存null.
  • 框架不支持修改时自动将null呈现为”,且保存时自动”改为null

Rust图形用户界面(GUI)推荐

iced

A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm.


struct Counter {
    // The counter value
    value: i32,
}

#[derive(Debug, Clone, Copy)]
pub enum Message {
    IncrementPressed,
    DecrementPressed,
}

use iced::widget::{button, column, text, Column};

impl Counter {
    pub fn view(&self) -> Column<Message> {
        // We use a column: a simple vertical layout
        column![
            // The increment button. We tell it to produce an
            // `IncrementPressed` message when pressed
            button("+").on_press(Message::IncrementPressed),

            // We show the value of the counter here
            text(self.value).size(50),

            // The decrement button. We tell it to produce a
            // `DecrementPressed` message when pressed
            button("-").on_press(Message::DecrementPressed),
        ]
    }

    pub fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            }
            Message::DecrementPressed => {
                self.value -= 1;
            }
        }
    }
}

Features

  • Simple, easy-to-use, batteries-included API
  • Type-safe, reactive programming model
  • Cross-platform support (Windows, macOS, Linux, and the Web)
  • Responsive layout
  • Built-in widgets (including text inputs, scrollables, and more!)
  • Custom widget support (create your own!)
  • Debug overlay with performance metrics
  • First-class support for async actions (use futures!)
  • Modular ecosystem split into reusable parts:
    • A renderer-agnostic native runtime enabling integration with existing systems
    • Two built-in renderers leveraging wgpu and glow
      • iced_wgpu supporting Vulkan, Metal and DX12
      • iced_glow supporting OpenGL 2.1+ and OpenGL ES 2.0+
    • A windowing shell
    • A web runtime leveraging the DOM

dioxus

Dioxus 是一个可移植的、高性能的、符合人体工程学的框架,使用 Rust 语言构建跨平台的用户界面。

fn app(cx: Scope) -> Element {
    let mut count = use_state(cx, || 0);

    cx.render(rsx! {
        h1 { "High-Five counter: {count}" }
        button { onclick: move |_| count += 1, "Up high!" }
        button { onclick: move |_| count -= 1, "Down low!" }
    })
}

Dioxus 可用于生成 网页前端、桌面应用、静态网站、移动端应用、TUI程序、等多类平台应用。

如果你能够熟悉使用 React 框架,那 Dioxus 对你来说将非常简单。

独特的特性:

  1. 桌面程序完全基于本地环境运行(并非 Electron 的封装)
  2. 符合人体工程学的设计以及拥有强大的状态管理
  3. 全面的内联文档 – 包含所有 HTML 元素、监听器 和 事件 指南。
  4. 极快的运行效率和极高的内存效率
  5. 智能项目热更新和高效的项目迭代
  6. 一流的异步支持fire
  7. 更多内容请查看 版本发布信息.

tauri

Build smaller, faster, and more secure desktop applications with a web frontend.

Features

  • Desktop Bundler (.app, .dmg, .deb, AppImage, .msi)
  • Self Updater
  • App Signing
  • Native Notifications (toast)
  • App Tray
  • Core Plugin System
  • Scoped Filesystem
  • Sidecar

Security Features

  • localhost-free (:fire:)
  • custom protocol for secure mode
  • Dynamic ahead of Time Compilation (dAoT) with functional tree-shaking
  • functional Address Space Layout Randomization
  • OTP salting of function names and messages at runtime
  • CSP Injection

Utilities

  • Rust-based CLI
  • GH Action for creating binaries for all platforms
  • VS Code Extension

egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native

ui.heading("My egui Application");
ui.horizontal(|ui| {
    ui.label("Your name: ");
    ui.text_edit_singleline(&mut name);
});
ui.add(egui::Slider::new(&mut age, 0..=120).text("age"));
if ui.button("Click each year").clicked() {
    age += 1;
}
ui.label(format!("Hello '{}', age {}", name, age));

yew

A framework for creating reliable and efficient web applications.

use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let counter = use_state(|| 0);
    let onclick = {
        let counter = counter.clone();
        move |_| {
            let value = *counter + 1;
            counter.set(value);
        }
    };

    html! {
        <div>
            <button {onclick}>{ "+1" }</button>
            <p>{ *counter }</p>
        </div>
    }
}

fn main() {
    yew::Renderer::<App>::new().render();
}

slint

Design Goals

We use the following design goals as a guide when developing Slint:

  • Scalable: Run on any screen connected to a device, from desktop computers to low end embedded systems.
  • Lightweight: Fit into a few hundred kilobytes of RAM and require little processing power.
  • Intuitive: Both developers and designers should feel productive and enjoy the design and development process. The APIs should be consistent and easy to use, no matter the target language.
  • Native: Slint apps should match the users’ expectations of a native application. Various target platforms such as embedded devices, desktops, mobile and web should be supported so that both the user and the developer feel comfortable on their platform of choice.