入参自动转换枚举


/**
* 定义一个枚举
*
*/
@Getter
public enum StatusType {

    SUCCESS("1","成功"),
    FAIL("2","失败"),
    PROCESSING("3","进行中"),
    ;

    StatusType(String code,String desc){
        this.code = code;
        this.desc = desc;
    }

    private String code;
    private String desc;

    public static StatusType getEnum(String code){
       return Stream.of(values())
                .filter(a -> a.code.equals(code))
                .findFirst()
                .orElseThrow(UnsupportedOperationException::new);
    }
}








import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/*
* 编写config配置
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StatusTypeConverter());
    }
}










import org.springframework.core.convert.converter.Converter;

/**
*    编写转换器
*/
public class StatusTypeConverter implements Converter<String, StatusType> {

    @Override
    public StatusType convert(String source) {
        return StatusType.getEnum(source);
    }
}




具体使用直接将controller层入参的status用StatusType接收即可。

@NotNull(message = "入参状态字段不能为空!")
private StatusType statusCode;

 

<think>首先,用户的问题是:“我想在C语言中如何传递数作为void指针 请问C语言函数类型为void *arg时如何正确传数”。这涉及到C语言中void指针的使用。 关键点是:函数数是void *arg,我需要解释如何正确传数。 从系统指令中,我有几个引用: - 引用[1]:关于void关键字的使用规则,包括第3点:如果函数的数可以是任意类型指针,那么应声明其数为void *。 - 引用[2]:关于va_arg宏的陷阱,提到char、short等类型会被提升。 - 引用[3]:一个示例代码,展示了可变数函数的使用,包括va_list、va_start、va_arg等。 用户的问题不是关于可变数的,而是关于如何传递数给一个接受void *的函数。引用[3]中的代码是可变数的例子,但用户的问题更简单:就是如何传递任意类型的指针给void *数。 所以,我需要专注于void *的基本用法。 在C语言中,void *是一个通用指针类型,可以指向任何数据类型。当你有一个函数声明为void func(void *arg),你可以传递任何指针类型的给它,因为void *可以隐式转换为其他指针类型。 规则: 1. 当你调用函数时,传递指针数时,不需要显式转换;C语言允许将任何指针类型赋给void *。 2. 在函数内部,当你使用arg时,你需要将其转换回适当的类型。 例如: - 如果你想传递一个int指针,你可以传递&some_int。 - 在函数内部,你需要将arg转换为int *,然后使用。 类似地,对于char *、struct *等。 引用[1]的第3点直接相关:如果函数的数可以是任意类型指针,那么应声明其数为void *。 所以,在回答中,我应该: - 解释void *的概念。 - 展示如何声明和定义这样的函数。 - 给出调用示例。 - 注意潜在问题,比如类型安全。 用户的问题中没有提到可变数,所以引用[2]和[3]可能不直接相关,但引用[3]有一个例子,我可以考它的一部分。 现在,回答结构: - 系统指令要求回答结构清晰,逐步解决问题。 - 使用中文。 - 行内数学表达式用$...$,但这里可能没有数学表达式。 - 独立公式用$$...$$,但可能不需要。 - 生成相关问题。 - 在引用段落末尾添加引用标识,如[^1]。 引用来源是给定的,所以我需要适当地引用它们。 步骤: 1. 解释void *的作用。 2. 描述如何声明函数。 3. 展示如何调用函数:传递数。 4. 在函数内部如何安全地使用数。 5. 给出代码示例。 6. 讨论潜在问题,比如类型转换错误。 7. 生成相关问题。 最后,添加相关问题。 相关问题应该基于主题,比如: - void *的其他用途? - 类型安全在C中的重要性? - 如何避免void *的误用? 确保回答真实可靠。 大纲回答: 1. 介绍void *:在C语言中,void *是一种通用指针类型,可以指向任意数据类型。这使得函数可以接受不同类型的指针作为数。 2. 声明函数:例如,void my_function(void *arg)。 3. 调用函数:当调用时,传递任何指针类型的。例如,如果有一个int变量,传递&int_var;如果有一个char数组,传递char_array。 4. 在函数内部:使用arg前,必须将其转换为正确的类型。例如,如果期望int,就做(int *)arg。 5. 代码示例:提供一个简单的例子。 6. 注意事项:确保转换的类型正确,否则可能导致未定义行为。引用[1]支持这一点。 7. 引用:在相关部分添加引用标识。 例如,在解释时,说“如引用[1]所述,void *用于允许任意类型指针数。” 8. 生成相关问题。</think>### C语言中传递数作为void指针的指南 在C语言中,void指针(`void *`)是一种通用指针类型,它允许函数接受任意类型的指针作为数。这使得函数更加灵活,可以处理多种数据类型。但使用时需要注意类型转换的安全性,以避免运行时错误。以下我将逐步解释如何正确声明、调用和使用void指针数,确保代码可靠。 #### 1. **void指针的基本概念** - `void *`是一个“无类型”指针,它可以指向任何数据类型的地址,但本身不包含类型信息。 - 如引用[1]所述:如果函数的数可以是任意类型指针,那么应声明其数为`void *`。这允许函数接受不同指针类型,而无需重载函数[^1]。 - 关键点:调用函数时,传递任何指针类型(如`int *`、`char *`)都会被隐式转换为`void *`;在函数内部,必须将`void *`显式转换回原始类型才能使用。 #### 2. **如何声明和定义函数** - **声明函数**:在函数原型中,使用`void *`作为数类型。例如: ```c void process_data(void *arg); // 声明一个接受void指针的函数 ``` - **定义函数**:在函数实现中,先检查数有效性(如非空),然后根据预期类型进行转换。例如,如果`arg`预期指向整数: ```c void process_data(void *arg) { if (arg == NULL) { printf("错误:数不能为空\n"); return; } int *ptr = (int *)arg; // 显式转换为int指针 printf(": %d\n", *ptr); // 使用转换后的指针 } ``` - **为什么需要转换**:`void *`本身不能直接解引用(如`*arg`),因为它没有类型信息。必须先转换为具体类型(如`int *`),才能访问数据。 #### 3. **如何正确传数** - 调用函数时,直接传递任何指针类型的变量。C语言会自动将指针隐式转换为`void *`,无需额外操作。 - **步骤**: 1. 确定要传递的数据类型(如整数、字符串、结构体)。 2. 获取该数据的指针(使用`&`运算符或数组名)。 3. 调用函数,传该指针。 - **示例代码**: ```c #include <stdio.h> // 函数声明 void print_value(void *arg); int main() { int num = 42; char str[] = "Hello"; float f = 3.14f; // 传递int指针:隐式转换为void * print_value(&num); // 传递char指针(字符串):隐式转换为void * print_value(str); // 传递float指针:隐式转换为void * print_value(&f); return 0; } // 函数定义:处理void *数 void print_value(void *arg) { // 假设arg可能指向不同类型,这里需要知道预期类型。 // 实际中,通常通过额外数(如枚举)指定类型,或使用统一接口。 // 本例简化:假设arg指向int(实际需根据上下文调整) int *int_ptr = (int *)arg; printf(": %d\n", *int_ptr); // 注意:如果传非int指针,这里会出错! } ``` - **输出警告**:上述代码在传`str`或`&f`时会输出错误,因为转换类型不匹配。这突显了类型安全的重要性(见注意事项)。 #### 4. **注意事项和最佳实践** - **类型安全**:`void *`会绕过编译器类型检查,错误转换可能导致崩溃或未定义行为。例如: - 如果传`char *`但转换为`int *`,解引用时可能访问错误内存。 - 解决方案:使用额外数指定类型(如枚举或字符串标识),或在函数内部实现类型分发。 - **指针大小和兼容性**:所有指针类型在内存中大小相同(通常4或8字节),因此`void *`转换是安全的。但指向的数据类型必须匹配使用场景。 - **避免常见错误**: - 不要传递非指针数据(如直接传递`int`),必须传递指针。 - 如引用[2]所述,类似`va_arg`的陷阱:某些类型(如`char`)会被提升为`int`,但`void *`转换不涉及此问题,因为它处理指针而非[^2]。 - 确保在函数内部转换时,类型与调用时一致。引用[3]中的示例展示了如何通过代码逻辑处理不同类型,但它是针对可变数的;对于`void *`,可以借鉴类似类型检查机制[^3]。 - **性能考虑**:`void *`转换是编译时操作,无运行时开销,但错误使用会增加调试难度。 #### 5. **改进示例:安全类型处理** 为了更可靠,可以添加类型标识数。例如: ```c #include <stdio.h> // 定义类型枚举 typedef enum { TYPE_INT, TYPE_FLOAT, TYPE_STRING } DataType; // 函数声明,添加类型数 void safe_print(void *arg, DataType type); int main() { int num = 42; float f = 3.14f; char str[] = "World"; safe_print(&num, TYPE_INT); safe_print(&f, TYPE_FLOAT); safe_print(str, TYPE_STRING); // str是char *,隐式转为void * return 0; } // 函数定义:根据类型安全转换 void safe_print(void *arg, DataType type) { if (arg == NULL) { printf("数为空\n"); return; } switch (type) { case TYPE_INT: { int *ptr = (int *)arg; printf("整数: %d\n", *ptr); break; } case TYPE_FLOAT: { float *ptr = (float *)arg; printf("浮点数: %.2f\n", *ptr); break; } case TYPE_STRING: { char *ptr = (char *)arg; printf("字符串: %s\n", ptr); break; } default: printf("未知类型\n"); } } ``` - **输出**: ``` 整数: 42 浮点数: 3.14 字符串: World ``` - **优点**:通过`DataType`数确保类型匹配,避免了未定义行为。 ### 总结 在C语言中,当函数数为`void *arg`时,正确传数的方法是:直接传递任何指针类型(如`&int_var`或`char_array`),并在函数内部显式转换为预期类型。关键是要保证类型转换的一致性,否则可能引发严重错误。如引用[1]强调,`void *`用于通用指针数是标准做法,但需谨慎处理类型安全[^1]。实际应用中,结合类型标识或统一接口可提升代码可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值