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

Maui学习笔记- SQLite简单使用案例02添加详情页

  • 我们继续上一个案例,实现一个可以修改当前用户信息功能。

    当用户点击某个信息时,跳转到信息详情页,然后可以点击编辑按钮导航到编辑页面。

创建项目 

  • 我们首先在ViewModels目录下创建UserDetailViewModel。

  • 实现从详情信息页面导航到编辑页面。

  • 这里要使用一个字典来传输对象。

public partial class UserDetailViewModel:ObservableObject,IQueryAttributable
{[ObservableProperty] private User itemUser;public Func<User, Task> ParentRefreshAction { get;set; }[RelayCommand]async Task ShowEditFormAsync(){var context = new UserContext();var editedItem = context.Users.FirstOrDefault(u => u.Id == ItemUser.Id);await Shell.Current.GoToAsync(nameof(UserEditPage),parameters: new Dictionary<string, object>{{ "ParentRefreshAction", (Func<User, Task>)ItemEditedAsync },{ "Item", editedItem }});}async Task ItemEditedAsync(User user) {ItemUser = user;await ParentRefreshAction(user);}public virtual void ApplyQueryAttributes(IDictionary<string, object> query){if (query.TryGetValue("Item",out object currentItem)){ItemUser = (User)currentItem;}if (query.TryGetValue("ParentRefreshAction",out object parentRefreshAction)){ParentRefreshAction = (Func<User, Task>)parentRefreshAction;}query.Clear();}
}
  • 创建用户详情页面,用来显示用户的全部信息。

  • 在ToolbarItem中添加一个命令导航到编辑页面。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:vm="clr-namespace:MauiApp3.ViewModels"Title="用户详情"x:Class="MauiApp3.Views.UserDetailPage"><ContentPage.BindingContext><vm:UserDetailViewModel/></ContentPage.BindingContext><ContentPage.ToolbarItems><ToolbarItem Text="编辑" Command="{Binding ShowEditFormCommand}"/></ContentPage.ToolbarItems><VerticalStackLayout><Label Text="{Binding ItemUser.Id}" FontSize="Large"/><Label Text="{Binding ItemUser.Name}" FontSize="Large"/><Label Text="{Binding ItemUser.Phone}" FontSize="Large"/><Label Text="{Binding ItemUser.Email}" FontSize="Large"/></VerticalStackLayout>
</ContentPage>
  • 更新UserEditViewModel,我们让他直接继承自UserDetailViewModel.

public partial class UserEditViewModel:UserDetailViewModel
{[ObservableProperty] private bool isNewItem;[RelayCommand]private async Task SaveAsync(){await using var context = new UserContext();if (IsNewItem){context.Users.Add(ItemUser);}else{context.Users.Attach(ItemUser);context.Entry(ItemUser).State = Microsoft.EntityFrameworkCore.EntityState.Modified;}context.SaveChangesAsync();await ParentRefreshAction(ItemUser);await Shell.Current.GoToAsync("..");}public override void ApplyQueryAttributes(IDictionary<string, object> query) {if (query.TryGetValue("IsNewItem", out object isNew)) {IsNewItem = (bool)isNew;}base.ApplyQueryAttributes(query);}
}

 

  • 修改MainViewModel。

public partial class MainViewModel:ObservableObject
{[ObservableProperty]ObservableCollection<User> users;[ObservableProperty] private bool refreshing;[RelayCommand]private async Task LoadUsersAsync(){await Task.Run(() =>{using var context = new UserContext();Users = new ObservableCollection<User>(context.Users);});Refreshing = false;}[RelayCommand]private void Showing(){Refreshing = true;}[RelayCommand]private void DeleteUser(User user){var context = new UserContext();context.Users.Remove(user);context.SaveChanges();Users.Remove(user);}[RelayCommand]private async Task ShowNewFormAsync(){await Shell.Current.GoToAsync(nameof(UserEditPage),parameters:new Dictionary<string, object>{{"ParentRefreshAction",(Func<User,Task>)RefreshAddedAsync},{"Item",new User()},{"IsNewItem",true}});}Task RefreshAddedAsync(User addedUser){Users.Add(addedUser);return Task.CompletedTask;}[RelayCommand]async Task ShowDetailFormAsync(User user){await Shell.Current.GoToAsync(nameof(UserDetailPage),parameters:new Dictionary<string, object>{{"ParentRefreshAction",(Func<User,Task>)RefreshEditedAsync},{"Item",user},});}async Task RefreshEditedAsync(User updataUser){int editedItemIndex = -1;await Task.Run(() =>{editedItemIndex = Users.Select((user, index) => new { user, index }).First(x => x.user.Id == updataUser.Id).index;});if (editedItemIndex==-1){return;}Users[editedItemIndex] = updataUser;}
}
  • 注册路由

public partial class AppShell : Shell
{public AppShell(){InitializeComponent();Routing.RegisterRoute(nameof(UserEditPage),typeof(UserEditPage));Routing.RegisterRoute(nameof(UserDetailPage),typeof(UserDetailPage));}
}

 

  • 在主页添加GestureRecognizers,对详情页面的跳转

<Grid RowDefinitions="40,40"ColumnDefinitions="*,*"Padding="10"><Grid.GestureRecognizers><TapGestureRecognizerCommand="{Binding Path=BindingContext.ShowDetailFormCommand,Source={RelativeSource Mode=FindAncestor,AncestorType={x:Type ContentPage}}}"CommandParameter="{Binding}"/></Grid.GestureRecognizers>
 IOS下运行程序

 

我们实现了查看用户详情,并且可以修改

优化代码 

  • 我们要在数据库和视图模型之间提供一个抽象层,它能使项目有不同的模块区分,更明确的分离开。

  • 在项目中往往需要对多张表进行操作,我们创建一个泛型接口,来抽象对数据库中CURD。

  • 在Models中添加一个IRepository.cs文件

public interface IRepository<T> where T:class
{Task<T> GetByIdAsync(int id);Task<IEnumerable<T>> GetAllAsync();Task AddAsync(T item);Task UpdateAsync(T item);Task DeleteAsync(T item);}
  • 实现接口

public class UserRepository: IRepository<User>
{private readonly DbSet<User> DbSet;private readonly UserContext Context;public UserRepository(UserContext context){Context = context;DbSet = Context.Set<User>();}public async Task<User> GetByIdAsync(int id){return await Task.Run(() => DbSet.Find(id));}public async Task<IEnumerable<User>> GetAllAsync(){return await Task.Run(() => DbSet.ToList());}public async Task AddAsync(User item){DbSet.Add(item);await Task.CompletedTask;}public async Task UpdateAsync(User item){DbSet.Attach(item);Context.Entry(item).State = EntityState.Modified;await Task.CompletedTask;}public async Task DeleteAsync(User item){DbSet.Remove(item);await Task.CompletedTask;}
  • 创建工作单元,它的作用主要是作用于不同的数据表。

public class DbUnitOfWork:IDisposable,IUnitOfWork<User>
{readonly UserContext Context=new UserContext();private IRepository<User> userRepository;public IRepository<User> Items => userRepository ??= new UserRepository(Context);public void Dispose(){Context.Dispose();}public async Task SaveAsync(){await Task.Run(() => Context.SaveChangesAsync());}
}public interface IUnitOfWork<T> where T : class {IRepository<T> Items { get; } Task SaveAsync(); 
}
修改MainViewModel
  • LoadUserAsync

[RelayCommand]
private async Task LoadUsersAsync()
{using var uniOfWork = new DbUnitOfWork();Users = new ObservableCollection<User>(await uniOfWork.Items.GetAllAsync());Refreshing = false;
}
  • DeleteUserAsync

[RelayCommand]
private async Task DeleteUser(User user)
{using var uniOfWork = new DbUnitOfWork();await uniOfWork.Items.DeleteAsync(user);await uniOfWork.SaveAsync();Users.Remove(user);
}
修改CustomerEditViewModel
  • SaveAsync

[RelayCommand]
private async Task SaveAsync()
{using var unitOfWork = new DbUnitOfWork();if (IsNewItem)await unitOfWork.Items.AddAsync(ItemUser);elseawait unitOfWork.Items.UpdateAsync(ItemUser);await unitOfWork.SaveAsync();await ParentRefreshAction(ItemUser);await Shell.Current.GoToAsync("..");
}
修改UserDetailViewModel
  • ShowEditFormAsync

[RelayCommand]
async Task ShowEditFormAsync()
{using var unitOfWork = new DbUnitOfWork();var editedItem = await unitOfWork.Items.GetByIdAsync(ItemUser.Id);await Shell.Current.GoToAsync(nameof(UserEditPage),parameters: new Dictionary<string, object>{{ "ParentRefreshAction", (Func<User, Task>)ItemEditedAsync },{ "Item", editedItem }});
}

 数据库验证错误

  • 很多时候我们需要对用户输入的数据进行验证,有很多方法和形式,我们来看看在数据库层面如何做错误验证处理。并反馈在页面给用户。

  • 我们在UserContext中进行简单的数据约束

  • 使用try catch来捕获异常

protected override void OnModelCreating(ModelBuilder modelBuilder)
{//用户邮箱唯一modelBuilder.Entity<User>().HasIndex(u => u.Email).IsUnique();//用户名不能为空modelBuilder.Entity<User>().Property(u => u.Name).IsRequired();//初始化数据modelBuilder.Entity<User>().HasData(new User{Id = 1,Name = "张三",Email = "张三@163.com",Phone = "123456789"});base.OnModelCreating(modelBuilder);
}
修改MainViewModel
  • DeleteCustomerAsync

[RelayCommand]
private async Task DeleteUserAsync(User user)
{using var uniOfWork = new DbUnitOfWork();try{await uniOfWork.Items.DeleteAsync(user);await uniOfWork.SaveAsync();}catch (Exception ex){await Shell.Current.DisplayAlert("Error", ex.Message, "OK");return;}Users.Remove(user);
}
修改UserEditViewModel
  • SaveAsync

[RelayCommand]
private async Task SaveAsync()
{using var unitOfWork = new DbUnitOfWork();try{if (IsNewItem)await unitOfWork.Items.AddAsync(ItemUser);elseawait unitOfWork.Items.UpdateAsync(ItemUser);await unitOfWork.SaveAsync();}catch (Exception ex){await Shell.Current.DisplayAlert("Error", ex.Message, "OK");return;}await ParentRefreshAction(ItemUser);await Shell.Current.GoToAsync("..");
}
IOS下运行程序
  • 这里如果用户没有添加用户名,程序会提出错误信息。

在UI中验证数据 

  • 程序中,在将数据提交到数据库之前可以在UI层执行某些验证规则,可以在用户保存某些修改时告知用户,从而改善用户体验。

修改UserEditViewModel
  • 在编辑用户页面我们添加对用户名和邮箱的验证,并关联到保存命令上。

[NotifyCanExecuteChangedFor(nameof(SaveCommand))] [ObservableProperty]
private bool isEmailValid;[NotifyCanExecuteChangedFor(nameof(SaveCommand))] [ObservableProperty]
private bool isNameValid;bool CanSave() => IsEmailValid&& IsNameValid;[RelayCommand(CanExecute = nameof(CanSave))]
private async Task SaveAsync()
{using var unitOfWork = new DbUnitOfWork();try{if (IsNewItem)await unitOfWork.Items.AddAsync(ItemUser);elseawait unitOfWork.Items.UpdateAsync(ItemUser);await unitOfWork.SaveAsync();}catch (Exception ex){await Shell.Current.DisplayAlert("Error", ex.Message, "OK");return;}await ParentRefreshAction(ItemUser);await Shell.Current.GoToAsync("..");
}

 

  • 在UserEditPage文件中,我们添加一个样式来反馈给用户,并使用工具包中的ValidationBehavior来进行验证和绑定命令。

  • 这个验证很简单,当用户输入的内容不满足条件时,会使用我们设置的样式颜色来显示,保存按钮无法点击,当满足条件时颜色变为正常并可以保存内容。

  • <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:vm="clr-namespace:MauiApp3.ViewModels;assembly=MauiApp3"xmlns:toolkit = "http://schemas.microsoft.com/dotnet/2022/maui/toolkit"x:Class="MauiApp3.Views.UserEditPage"Title="新用户"><ContentPage.BindingContext><vm:UserEditViewModel/></ContentPage.BindingContext><ContentPage.Resources><Style TargetType="Entry" x:Key="invalidEntryStyle"><Setter Property="TextColor" Value="Red"></Setter></Style></ContentPage.Resources><Grid><VerticalStackLayout VerticalOptions="Start"><Entry Placeholder="用户名"Text="{Binding ItemUser.Name}"><Entry.Behaviors><toolkit:TextValidationBehavior InvalidStyle="{StaticResource invalidEntryStyle}"IsValid="{Binding IsNameValid}"Flags="ValidateOnValueChanged,ValidateOnAttaching"//内容长度不能小于5MinimumLength="5"/></Entry.Behaviors></Entry><Entry Placeholder="电话"Text="{Binding ItemUser.Phone}"/><Entry Placeholder="Email"Text="{Binding ItemUser.Email}"ReturnCommand="{Binding SaveCommand}"><Entry.Behaviors>//验证是否时正常的邮箱格式<toolkit:EmailValidationBehaviorInvalidStyle="{StaticResource invalidEntryStyle}"IsValid="{Binding IsEmailValid}"Flags="ValidateOnValueChanged,ValidateOnAttaching"/></Entry.Behaviors></Entry><Button Text="保存" Command="{Binding SaveCommand}"/></VerticalStackLayout><ActivityIndicator VerticalOptions="Center"HorizontalOptions="Center"IsRunning="{Binding SaveCommand.IsRunning}"/></Grid>
    </ContentPage>

IOS下运行程序 

相关文章:

Maui学习笔记- SQLite简单使用案例02添加详情页

我们继续上一个案例&#xff0c;实现一个可以修改当前用户信息功能。 当用户点击某个信息时&#xff0c;跳转到信息详情页&#xff0c;然后可以点击编辑按钮导航到编辑页面。 创建项目 我们首先在ViewModels目录下创建UserDetailViewModel。 实现从详情信息页面导航到编辑页面…...

VMware 中Ubuntu无网络连接/无网络标识解决方法【已解决】

参考文档 Ubuntu无网络连接/无网络标识解决方法_ubuntu没网-CSDN博客 再我们正常使用VMware时&#xff0c;就以Ubuntu举例可能有时候出现无网络连接&#xff0c;甚至出现无网络标识的情况&#xff0c;那么废话不多说直接上教程 环境&#xff1a;无网络 解决方案&#…...

完美世界前端面试题及参考答案

如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...

新时代架构SpringBoot+Vue的理解(含axios/ajax)

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue&#xff08;前端&#xff09;axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 引言 我是一个喜欢知其然又知其所以然的…...

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…...

gif动画图像优化,相同的图在第2,4,6帧中重复出现,会增加图像体积吗?

对于 GIF 图像&#xff0c;情况与 Git 文件存储有所不同。GIF 是一种图像格式&#xff0c;其体积主要取决于图像的内容、颜色数量、优化设置等因素。如果在 GIF 动画中&#xff0c;相同的图像在第 2、4、6 帧中重复出现&#xff0c;是否会增加图像体积&#xff0c;取决于以下几…...

Harmony Next 跨平台开发入门

ArkUI-X 官方介绍 官方文档&#xff1a;https://gitee.com/arkui-x/docs/tree/master/zh-cn ArkUI跨平台框架(ArkUI-X)进一步将ArkUI开发框架扩展到了多个OS平台&#xff1a;目前支持OpenHarmony、Android、 iOS&#xff0c;后续会逐步增加更多平台支持。开发者基于一套主代码…...

阿里巴巴Qwen团队发布AI模型,可操控PC和手机

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

android 音视频系列引导

音视频这块的知识点自己工作中有用到&#xff0c;一直没有好好做一个总结&#xff0c;原因有客观和主观的。 客观是工作太忙&#xff0c;没有成段时间做总结。 主观自己懒。 趁着这次主动离职拿了n1的钱&#xff0c;休息一下&#xff0c;对自己的人生做一下总结&#xff0c;…...

STM32调试手段:重定向printf串口

引言 C语言中经常使用printf来输出调试信息&#xff0c;打印到屏幕。由于在单片机中没有屏幕&#xff0c;但是我们可以重定向printf&#xff0c;把数据打印到串口&#xff0c;从而在电脑端接收调试信息。这是除了debug外&#xff0c;另外一个非常有效的调试手段。 一、什么是pr…...

基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结

title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付&#xff08;CI/CD&#xff09;流程里&#xff0c;及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...

Vue.js组件开发-实现导出PDF文件可自定义添加水印及水印样式方向

使用 Vue 实现导出 PDF 文件并添加水印&#xff0c;同时支持设置水印样式、方向和自定义水印内容。 步骤 安装依赖&#xff1a;使用 html2canvas 将 HTML 内容转换为 canvas&#xff0c;使用 jspdf 生成 PDF 文件。创建 Vue 组件&#xff1a;在组件中实现水印生成、HTML 转 c…...

css中的animation

css的animation animation是一个综合属性,是animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state, and animation-timeline这些属性的简写 不过在…...

四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)

四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09; 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09;2.hash 哈希表常用指令(详细讲解说明)2.1 hset …...

基于Springboot + vue实现的洗衣店订单管理系统

“前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能学习网站” &#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜…...

用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南

本篇将主要讲讲如何用「Scoop」优雅管理 Windows 软件&#xff1a;安装、配置与使用全指南 一、Scoop 是什么&#xff1f; Scoop 是一款专为 Windows 设计的命令行软件包管理工具&#xff0c;它能让你像 Linux 系统一样通过命令快速安装、更新和卸载软件。其核心优势包括&…...

深度学习中常用的评价指标方法

深度学习中常用的评价指标方法因任务类型&#xff08;如分类、回归、分割等&#xff09;而异。以下是一些常见的评价指标&#xff1a; 1. 分类任务 准确率&#xff08;Accuracy&#xff09; 定义&#xff1a;正确预测的样本数占总样本数的比例。 公式&#xff1a;AccuracyTPT…...

多协议网关BL110钡铼6路RS485转MQTT协议云网关

多协议网关BL110钡铼6路RS485转MQTT协议云网关是一款集成了多种通信协议的工业级网关设备&#xff0c;专为物联网&#xff08;IoT&#xff09;应用设计。该网关能够将RS485总线设备的数据转化为MQTT协议&#xff0c;通过网络传输到云平台&#xff0c;实现远程监控和数据管理。以…...

Nginx 安装配置指南

Nginx 安装配置指南 引言 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;同时也可以作为 IMAP/POP3/SMTP 代理服务器。由于其稳定性、丰富的功能集以及低资源消耗而被广泛应用于各种场景。本文将为您详细介绍 Nginx 的安装与配置过程。 系统要求 在安装 Nginx 之…...

二叉树介绍

一.树的概念 树的图&#xff1a; 1.结点的度&#xff1a;一个结点含有子树的个数称为该结点的度&#xff1b; 如上图&#xff1a;A的度为6 2.树的度&#xff1a;一棵树中&#xff0c;所有结点度的最大值称为树的度&#xff1b; 如上图&#xff1a;树的度为6 3.叶子结点或终…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

【WiFi帧结构】

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

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

基于Uniapp的HarmonyOS 5.0体育应用开发攻略

一、技术架构设计 1.混合开发框架选型 &#xff08;1&#xff09;使用Uniapp 3.8版本支持ArkTS编译 &#xff08;2&#xff09;通过uni-harmony插件调用原生能力 &#xff08;3&#xff09;分层架构设计&#xff1a; graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...