几种情况的二分写法

之前总是对二分的边界问题把握的不是很好,以致于出现死循环等问题。所以用这篇博文进行总结。
首先,本文所用算法均为左闭右闭的算法,且数组是以非递减顺序排列的。
1、查找是否存在关键值,如有相等的,则返回最左边的那个值的位置。否则,返回-1.

int binary_search_1(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭区间[0, n - 1]
    while (l < r)
    {
        m = l + ((r - l) / 2);//向下取整
        if (a[m] < key) 
            l = m + 1;
        else 
            r = m;
    }
    if (a[r] == key) return r;
    return -1;
}   

2、查找是否存在关键值,如有相等的,则返回最右边那个值得位置。否则,返回-1.

int binary_search_2(int a[], int n, int key)
{
    int m, l = 0, r = n - 1;//闭
<think>嗯,我现在要学习Vue 3中的defineEmits的几种写法。首先,我需要回忆一下Vue 3的Composition API,因为defineEmits是在这个里面使用的。记得在Vue 3中,组件之间的通信方式中,emit是用来子组件向父组件传递事件的。不过之前用的是选项式API中的emits选项,现在在Composition API里应该用defineEmits来定义事件。 首先,我需要了解defineEmits的基本用法。可能有两种写法:一种是运行时声明,另一种是类型声明,尤其是在使用TypeScript的时候。不过我不太确定具体怎么区分这两种写法。 比如,在选项式API中,我们会在emits选项中列出所有的事件名称,然后在方法里用this.$emit触发。但是在Composition API的setup函数中,应该用defineEmits来定义事件,然后返回一个触发事件的函数。 那defineEmits的运行时声明可能是什么样的?比如,可能直接传入一个事件名称数组,然后得到一个emit函数。例如: const emit = defineEmits(['update', 'submit']); 然后在需要的时候调用emit('update', value)。这种情况下,事件名称是通过数组来声明的,没有类型检查,适用于不使用TypeScript的情况。 另一种写法可能是使用TypeScript的类型声明,这样可以在开发时提供更好的类型检查和自动补全。比如,用泛型参数来定义事件的类型。例如: const emit = defineEmits<{ (e: 'update', value: number): void; (e: 'submit', data: FormData): void; }>(); 这里,每个事件都是一个函数类型,参数e是事件名称,后面是参数的类型。这样在触发emit的时候,就会有类型检查,确保传递的参数正确。 还有一种可能是在Vue 3.3+版本中引入了更简洁的语法,使用对象形式的类型声明。例如: const emit = defineEmits<{ update: [value: number]; submit: [data: FormData]; }>(); 这样每个事件对应一个数组类型的参数,表示事件处理函数的参数列表。这样写可能更直观,特别是当事件携带多个参数时。 不过,我不太确定这种对象形式的写法是从哪个版本开始支持的,可能需要Vue 3.3或更高版本。而之前的版本可能只能使用函数形式的类型声明。 还有,在组合式API中,defineEmits只能在setup函数中使用,并且是编译器宏,不需要显式导入。另外,当使用TypeScript时,可能需要配置好类型支持,比如在volar插件下才能正确识别类型声明。 另外,可能还存在一种不带声明的隐式用法,直接调用emit,但这样可能不会有类型检查,也不推荐使用。比如直接写emit('eventName'),但如果没有在defineEmits中声明,可能会在TypeScript中报错或者没有提示。 总结一下,defineEmits的几种写法可能包括: 1. 运行时声明:传入事件名称数组,适用于非TypeScript项目。 2. 类型声明(函数签名形式):使用泛型定义事件及其参数类型,适用于TypeScript。 3. 类型声明(对象形式):Vue 3.3+支持的更简洁的语法,同样适用于TypeScript。 还需要注意不同写法在参数传递时的区别。比如,当使用数组形式定义事件参数时,emit调用时的参数需要对应数组中的类型。例如,如果定义submit事件为[data: FormData, flag: boolean],那么调用emit('submit', formData, true)就需要传递这两个参数。 可能还需要举例说明每种写法对应的emit调用方式,以及如何在父组件中监听这些事件。比如,父组件中使用@update="handleUpdate",而子组件中emit('update', 123)。 另外,需要注意在类型声明中,事件的名称和参数类型必须严格匹配,否则TypeScript会报错,这有助于提前发现错误。 最后,可能还需要提一下最佳实践,比如推荐使用类型声明的方式,特别是在TypeScript项目中,以获得更好的类型安全和代码提示。而如果项目没有使用TypeScript,则可以使用运行时声明的方式。 总结起来,我需要分清楚这几种写法的适用场景、语法结构以及注意事项,并通过示例来展示每种写法如何实现,从而帮助用户理解和选择合适的方法。</think>在 Vue 3 的 Composition API 中,`defineEmits` 用于定义组件可触发的事件。以下是其常见的几种写法及使用场景: --- ### 一、运行时声明(非 TypeScript) 通过 **字符串数组** 声明事件名称,适合非 TypeScript 项目。 **语法**: ```javascript const emit = defineEmits(['update', 'submit']); ``` **使用示例**: ```javascript // 子组件 const emit = defineEmits(['update', 'submit']); // 触发事件 emit('update', 123); emit('submit', { data: 'test' }); ``` **父组件监听**: ```html <ChildComponent @update="handleUpdate" @submit="handleSubmit" /> ``` --- ### 二、类型声明(TypeScript 函数签名) 通过 **泛型函数签名** 定义事件参数类型,适合 TypeScript 项目。 **语法**: ```typescript const emit = defineEmits<{ (e: 'update', value: number): void; (e: 'submit', data: { id: string }): void; }>(); ``` **使用示例**: ```typescript // 子组件 const emit = defineEmits<{ (e: 'update', value: number): void; (e: 'submit', data: { id: string }): void; }>(); // 触发事件(参数类型会被校验) emit('update', 100); emit('submit', { id: 'abc' }); ``` --- ### 三、类型声明(Vue 3.3+ 对象语法) Vue 3.3+ 支持更简洁的 **对象语法**,直接定义事件参数类型。 **语法**: ```typescript const emit = defineEmits<{ update: [value: number]; submit: [data: { id: string }]; }>(); ``` **使用示例**: ```typescript // 子组件 const emit = defineEmits<{ update: [value: number]; submit: [data: { id: string }]; }>(); // 触发事件(参数顺序和类型需匹配) emit('update', 200); emit('submit', { id: 'def' }); ``` --- ### 四、注意事项 1. **类型校验**: TypeScript 模式下,参数类型和数量会被严格校验,避免运行时错误。 ```typescript emit('update', '字符串'); // ❌ 报错:类型不匹配 ``` 2. **多参数传递**: 若事件需要多个参数,可通过数组定义: ```typescript defineEmits<{ change: [id: string, status: boolean]; }>(); // 触发时:emit('change', '123', true); ``` 3. **无参数事件**: 若事件无参数,需显式声明空数组: ```typescript defineEmits<{ click: [] }>(); // 触发时:emit('click'); ``` --- ### 五、总结 | 写法 | 适用场景 | 特点 | |--------------------|-------------------|----------------------------------| | 运行时声明(数组) | 非 TypeScript 项目 | 简单易用,无类型检查 | | 类型声明(函数签名) | TypeScript 项目 | 严格的类型校验,支持复杂参数 | | 类型声明(对象语法) | Vue 3.3+ | 语法更简洁,直观定义参数类型 | 推荐优先使用 **TypeScript 类型声明**,尤其在复杂场景中,可大幅提升代码健壮性和开发体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值