11种编程语言中,返回多个不同类型的方法样例

打印 上一主题 下一主题

主题 495|帖子 495|积分 1485

本文分享自华为云社区《多语言编程 返回多个不同类型的方法样例》,作者: 张俭 。
背景

你可能会在一些场景下碰到需要返回多个不同类型的方法。比如协议解析读取报文时,更具体地像kubernetes在开始解析Yaml的时候,怎么知道这个类型是属于Deployment还是Service?
C

C语言通常通过使用Struct(结构体)和Union(联合体)的方式来实现这个功能,如下文例子
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef enum {
  5.     MONKEY,
  6.     COW,
  7.     UNKNOWN
  8. } AnimalType;
  9. typedef struct {
  10.     char* description;
  11. } Monkey;
  12. typedef struct {
  13.     char* description;
  14. } Cow;
  15. typedef struct {
  16.     AnimalType type;
  17.     union {
  18.         Monkey monkey;
  19.         Cow cow;
  20.     };
  21. } Animal;
  22. Animal createAnimal(const char* animalType) {
  23.     Animal animal;
  24.     if (strcmp(animalType, "Monkey") == 0) {
  25.         animal.type = MONKEY;
  26.         animal.monkey.description = "I am a monkey!";
  27.     } else if (strcmp(animalType, "Cow") == 0) {
  28.         animal.type = COW;
  29.         animal.cow.description = "I am a cow!";
  30.     } else {
  31.         animal.type = UNKNOWN;
  32.     }
  33.     return animal;
  34. }
  35. int main() {
  36.     Animal animal1 = createAnimal("Monkey");
  37.     if (animal1.type == MONKEY) {
  38.         printf("%s\n", animal1.monkey.description);
  39.     }
  40.     Animal animal2 = createAnimal("Cow");
  41.     if (animal2.type == COW) {
  42.         printf("%s\n", animal2.cow.description);
  43.     }
  44.     Animal animal3 = createAnimal("Dog");
  45.     if (animal3.type == UNKNOWN) {
  46.         printf("Unknown animal type\n");
  47.     }
  48.     return 0;
  49. }
复制代码
C++

在C++中,我们可以使用基类指针来指向派生类的对象。可以使用动态类型识别(RTTI)来在运行时确定对象的类型
  1. #include <iostream>
  2. #include <stdexcept>
  3. class Animal {
  4. public:
  5.     virtual std::string toString() const = 0;
  6. };
  7. class Monkey : public Animal {
  8. public:
  9.     std::string toString() const override {
  10.         return "I am a monkey!";
  11.     }
  12. };
  13. class Cow : public Animal {
  14. public:
  15.     std::string toString() const override {
  16.         return "I am a cow!";
  17.     }
  18. };
  19. Animal* createAnimal(const std::string& animalType) {
  20.     if (animalType == "Monkey") {
  21.         return new Monkey();
  22.     }
  23.     if (animalType == "Cow") {
  24.         return new Cow();
  25.     }
  26.     throw std::runtime_error("Unknown animal type: " + animalType);
  27. }
  28. int main() {
  29.     try {
  30.         Animal* animal1 = createAnimal("Monkey");
  31.         if (Monkey* monkey = dynamic_cast<Monkey*>(animal1)) {
  32.             std::cout << monkey->toString() << std::endl;
  33.         }
  34.         delete animal1;
  35.         Animal* animal2 = createAnimal("Cow");
  36.         if (Cow* cow = dynamic_cast<Cow*>(animal2)) {
  37.             std::cout << cow->toString() << std::endl;
  38.         }
  39.         delete animal2;
  40.     }
  41.     catch (const std::runtime_error& e) {
  42.         std::cerr << e.what() << std::endl;
  43.     }
  44.     return 0;
  45. }
复制代码
使用SealedClass
  1. package main
  2. import (
  3.     "fmt"
  4. )
  5. type Animal interface {
  6.     String() string
  7. }
  8. type Monkey struct{}
  9. func (m Monkey) String() string {
  10.     return "I am a monkey!"
  11. }
  12. type Cow struct{}
  13. func (c Cow) String() string {
  14.     return "I am a cow!"
  15. }
  16. func createAnimal(typeName string) (Animal, error) {
  17.     switch typeName {
  18.     case "Monkey":
  19.         return Monkey{}, nil
  20.     case "Cow":
  21.         return Cow{}, nil
  22.     default:
  23.         return nil, fmt.Errorf("Unknown animal type: %s", typeName)
  24.     }
  25. }
  26. func main() {
  27.     animal1, err := createAnimal("Monkey")
  28.     if err != nil {
  29.         fmt.Println(err)
  30.         return
  31.     }
  32.     if monkey, ok := animal1.(Monkey); ok {
  33.         fmt.Println(monkey)
  34.     }
  35.     animal2, err := createAnimal("Cow")
  36.     if err != nil {
  37.         fmt.Println(err)
  38.         return
  39.     }
  40.     if cow, ok := animal2.(Cow); ok {
  41.         fmt.Println(cow)
  42.     }
  43. }
复制代码
Python

Python是动态类型的语言,可以简单基于一些条件返回不同类型的对象,然后在接收到返回值之后使用type()函数或isinstance()函数来确定其类型
  1. public class MultiTypeReturnExample {
  2.     static class Monkey {
  3.         @Override
  4.         public String toString() {
  5.             return "I am a monkey!";
  6.         }
  7.     }
  8.     static class Cow {
  9.         @Override
  10.         public String toString() {
  11.             return "I am a cow!";
  12.         }
  13.     }
  14.     public static Object createAnimal(String type) throws IllegalArgumentException {
  15.         switch (type) {
  16.             case "Monkey":
  17.                 return new Monkey();
  18.             case "Cow":
  19.                 return new Cow();
  20.             default:
  21.                 throw new IllegalArgumentException("Unknown animal type: " + type);
  22.         }
  23.     }
  24.     public static void main(String[] args) throws Exception {
  25.         Object animal1 = createAnimal("Monkey");
  26.         // java8 写法,后面如果明确用做精确的类型,需要强制转换
  27.         if (animal1 instanceof Monkey) {
  28.             System.out.println(animal1);
  29.         }
  30.         Object animal2 = createAnimal("Cow");
  31.         if (animal2 instanceof Cow) {
  32.             System.out.println(animal2);
  33.         }
  34.         // java17 写法,不需要强制转换
  35.         if (createAnimal("Monkey") instanceof Monkey animal3) {
  36.             System.out.println(animal3);
  37.         }
  38.         if (createAnimal("Cow") instanceof Cow animal4) {
  39.             System.out.println(animal4);
  40.         }
  41.     }
  42. }
复制代码
Ruby

Ruby也较为简单,在方法内部直接返回不同类型的对象。然后,可以使用is_a方法或class方法来确定返回对象的实际类型。
  1. class Animal {
  2.     toString() {
  3.         return 'I am an animal';
  4.     }
  5. }
  6. class Monkey extends Animal {
  7.     toString() {
  8.         return 'I am a monkey';
  9.     }
  10. }
  11. class Cow extends Animal {
  12.     toString() {
  13.         return 'I am a cow';
  14.     }
  15. }
  16. function createAnimal(animalType) {
  17.     switch (animalType) {
  18.         case 'Monkey':
  19.             return new Monkey();
  20.         case 'Cow':
  21.             return new Cow();
  22.         default:
  23.             throw new Error(`Unknown animal type: ${animalType}`);
  24.     }
  25. }
  26. try {
  27.     const animal1 = createAnimal('Monkey');
  28.     if (animal1 instanceof Monkey) {
  29.         console.log(animal1.toString());
  30.     }
  31.     const animal2 = createAnimal('Cow');
  32.     if (animal2 instanceof Cow) {
  33.         console.log(animal2.toString());
  34.     }
  35.     const animal3 = createAnimal('Dog');
  36. } catch (error) {
  37.     console.error(error.message);
  38. }
复制代码
Rust

在Rust中,可以使用enum(枚举)来创建一个持有多种不同类型的数据结构。然后使用match语句来做模式匹配。
[code]use std::fmt;enum Animal {    Monkey,    Cow,}impl fmt:isplay for Animal {    fn fmt(&self, f: &mut fmt::Formatter
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦见你的名字

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表