function p = parseParameters(num, defaultVal, process_func, args)
% 代替 inputParser 的解析函数
    parameters = fieldnames(defaultVal);
    p = defaultVal;
    if isempty(args)
        return;
    end

    numPotional = 0; % 实际传入 Optional 参数个数
    n = length(args);
    % 默认规则：Optional 参数必须在 Name-Value 参数前面
    % 扫描所有参数 varargin, 找到第一个参数名, 前面的参数就是 Optional, 后面的参数就是 Name-Value
    for i = 1:n
        % 检查是否是有效的参数名
        if (ischar(args{i}) || isstring(args{i})) && any(strcmpi(args{i}, parameters))
            break;
        else
            numPotional = numPotional + 1;
        end
    end
    % Optional 参数个数最多为 num 个
    numPotional = min(numPotional, num);

    % 处理所有 Optional 参数
    for i = 1:numPotional
        field = parameters{i};
        val = args{i};
        try
            p.(field) = process_func(val);
        catch
            error(sprintf('第%d个参数输入了不支持的类型。', i));
        end
    end

    % 处理所有 Name-Value 参数
    if mod(n - numPotional, 2) ~= 0
        error("所有参数都必须具有关联的值");
    end
    for i = numPotional+1:2:n
        ind = strcmpi(parameters, args{i});

        if any(ind)
            field = parameters{ind};
            val = args{i + 1};

            if ~islogical(val)
                msg = sprintf("参数 ""%s"" 不支持该类型值 ""%s"".", field, string(val));
                error(msg);
            end

            p.(field) = val;
        else
            error(sprintf('无法识别的参数: %s', args{i}));
        end
    end
end
