草庐IT

javascript - 类型文本不受控制的输入被控制警告

coder 2024-07-27 原文

我正在尝试使用 React 和 Redux 创建一个多步骤注册表单。

主要组成部分如下:

import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as actionCreators from '../../actions/actionCreators';
import countries from '../../data/countries';

import RegistrationFormStepOne from './registrationFormStepOne';
import RegistrationFormStepTwo from './registrationFormStepTwo';
import RegistrationFormStepThree from './registrationFormStepThree';
import RegistrationFormStepFour from './registrationFormStepFour';

class RegistrationPage extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            user: Object.assign({}, this.props.userData),
            fileNames: {},
            selectedFile: {},
            icons: {
                idCard: 'upload',
                statuten: 'upload',
                blankLetterhead: 'upload',
                companyPhoto: 'upload'
            },
            step: 1,
            errors: {}
        };

        this.setUser = this.setUser.bind(this);
        this.onButtonClick = this.onButtonClick.bind(this);
        this.onButtonPreviousClick = this.onButtonPreviousClick.bind(this);
        this.changeCheckboxState = this.changeCheckboxState.bind(this);
        this.onFileChange = this.onFileChange.bind(this);
        this.routerWillLeave = this.routerWillLeave.bind(this);
    }

    componentDidMount() {
        this.context.router.setRouteLeaveHook(this.props.route, this.routerWillLeave);
    }

    routerWillLeave(nextLocation) {
        if (this.state.step > 1) {
            this.setState({step: this.state.step - 1});
            return false;
        }
    }

    getCountries(){
        return countries;
    }


    setUser(event) {
        const field = event.target.name;
        const value = event.target.value;

        let user = this.state.user;
        user[field] = value;
        this.setState({user: user});

    }

    validation(){
        const user = this.state.user;
        const languageReg = this.props.currentLanguage.default.registrationPage;
        let formIsValid = true;
        let errors = {};

        if(!user.companyName){
            formIsValid = false;
            errors.companyName = languageReg.companyNameEmpty;
        }

        if(!user.btwNumber){
            formIsValid = false;
            errors.btwNumber = languageReg.btwNumberEmpty;
        }

        if(!user.address){
            formIsValid = false;
            errors.address = languageReg.addressEmpty;
        }

        if(!user.country){
            formIsValid = false;
            errors.country = languageReg.countryEmpty;
        }

        if(!user.zipcode){
            formIsValid = false;
            errors.zipcode = languageReg.zipcodeEmpty;
        }

        if(!user.place){
            formIsValid = false;
            errors.place = languageReg.placeEmpty;
        }


        if(!user.firstName){
            formIsValid = false;
            errors.firstName = languageReg.firstnameEmpty;
        }



        this.setState({errors: errors});
        return formIsValid;
    }

    onFileChange(name, event) {
        event.preventDefault();
        let file = event.target.value;

        let filename = file.split('\\').pop(); //We get only the name of the file
        let filenameWithoutExtension = filename.replace(/\.[^/.]+$/, ""); //We get the name of the file without extension

        let user = this.state.user;
        let fileNames = this.state.fileNames;
        let selectedFile = this.state.selectedFile;
        let icons = this.state.icons;

        switch (name.btnName) {
            case "idCard" :
                fileNames[name.btnName] = filenameWithoutExtension;
                //Check if file is selected
                if(file){
                    selectedFile[name.btnName] = "fileSelected";
                    user["idCardFile"] = true;
                    icons["idCard"] = "check";
                }else{
                    selectedFile[name.btnName] = "";
                    user["idCardFile"] = false;
                    icons["idCard"] = "upload";
                }
                break;
            case "statuten" :
                fileNames[name.btnName] = filenameWithoutExtension;

                //Check if file is selected
                if(file){
                    selectedFile[name.btnName] = "fileSelected";
                    user["statutenFile"] = true;
                    icons["statuten"] = "check";
                }else{
                    selectedFile[name.btnName] = "";
                    user["statutenFile"] = false;
                    icons["statuten"] = "upload";
                }
                break;
            case "blankLetterhead" :
                fileNames[name.btnName] = filenameWithoutExtension;

                //Check if file is selected
                if(file){
                    selectedFile[name.btnName] = "fileSelected";
                    user["blankLetterheadFile"] = true;
                    icons["blankLetterhead"] = "check";
                }else{
                    selectedFile[name.btnName] = "";
                    user["blankLetterheadFile"] = false;
                    icons["blankLetterhead"] = "upload";
                }
                break;
            default:
                fileNames[name.btnName] = filenameWithoutExtension;
                //Check if file is selected
                if(file){
                    selectedFile[name.btnName] = "fileSelected";
                    user["companyPhotoFile"] = true;
                    icons["companyPhoto"] = "check";
                }else{
                    selectedFile[name.btnName] = "";
                    user["companyPhotoFile"] = false;
                    icons["companyPhoto"] = "upload";
                }
        }

        this.setState({user: user, fileNames: fileNames, selectedFile: selectedFile, icons: icons});
    }

    changeCheckboxState(event) {
        let chcName = event.target.name;
        let user = this.state.user;

        switch (chcName) {
            case "chcEmailNotificationsYes":
                user["emailNotifications"] = event.target.checked;
                break;
            case "chcEmailNotificationsNo":
                user["emailNotifications"] = !event.target.checked;
                break;
            case "chcTerms":
                if(typeof this.state.user.terms === "undefined"){
                    user["terms"] = false;
                }else{
                    user["terms"] = !this.state.user.terms;
                }

                break;
            case "chcSmsYes":
                user["smsNotifications"] = event.target.checked;
                break;
            default:
                user["smsNotifications"] = !event.target.checked;
        }
        this.setState({user: user});
        this.props.actions.userRegistration(this.state.user);
    }

    onButtonClick(name, event) {
        event.preventDefault();
        this.props.actions.userRegistration(this.state.user);
        switch (name) {
            case "stepFourConfirmation":
                this.setState({step: 1});
                break;
            case "stepTwoNext":
                this.setState({step: 3});
                break;
            case "stepThreeFinish":
                this.setState({step: 4});
                break;
            default:
                if(this.validation()) {
                   this.setState({step: 2});
                }
        }
    }


    onButtonPreviousClick(){
        this.setState({step: this.state.step - 1});
    }

    render() {
        const languageReg = this.props.currentLanguage.default.registrationPage;

        console.log(this.state.user);
        let formStep = '';
        let step = this.state.step;
        switch (step) {
            case 1:
                formStep = (<RegistrationFormStepOne user={this.props.userData}
                                                     onChange={this.setUser}
                                                     onButtonClick={this.onButtonClick}
                                                     countries={this.getCountries(countries)}
                                                     errors={this.state.errors}
                                                     step={step}/>);
                break;
            case 2:
                formStep = (<RegistrationFormStepTwo user={this.props.userData}
                                                     onChange={this.setUser}
                                                     onButtonClick={this.onButtonClick}
                                                     onButtonPreviousClick={this.onButtonPreviousClick}
                                                     errors={this.state.errors}/>);
                break;
            case 3:
                formStep = (<RegistrationFormStepThree user={this.props.userData}
                                                       onFileChange={this.onFileChange}
                                                       onButtonClick={this.onButtonClick}
                                                       onButtonPreviousClick={this.onButtonPreviousClick}
                                                       errors={this.state.errors}
                                                       fileNames={this.state.fileNames}
                                                       icons={this.state.icons}
                                                       fileChosen={this.state.selectedFile}/>);
                break;

            default:
                formStep = (<RegistrationFormStepFour user={this.props.userData}
                                                      onChange={this.setUser}
                                                      onChangeCheckboxState={this.changeCheckboxState}
                                                      onButtonClick={this.onButtonClick}
                                                      onButtonPreviousClick={this.onButtonPreviousClick}
                                                      errors={this.state.errors}/>);
        }

        return (
            <div className="sidebar-menu-container" id="sidebar-menu-container">

                <div className="sidebar-menu-push">

                    <div className="sidebar-menu-overlay"></div>

                    <div className="sidebar-menu-inner">
                        <div className="contact-form">
                            <div className="container">
                                <div className="row">
                                    <div className="col-md-10 col-md-offset-1 col-md-offset-right-1">
                                        {React.cloneElement(formStep, {currentLanguage: languageReg})}
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

RegistrationPage.contextTypes = {
    router: PropTypes.object
};

function mapStateToProps(state, ownProps) {
    return {
        userData: state.userRegistrationReducer
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(actionCreators, dispatch)
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(RegistrationPage);

第一步组件如下

    import React from 'react';
import Button from '../../common/formElements/button';
import RegistrationFormHeader from './registrationFormHeader';
import TextInput from '../../common/formElements/textInput';
import SelectInput from '../../common/formElements/selectInput';

const RegistrationFormStepOne = ({user, onChange, onButtonClick, errors, currentLanguage, countries}) => {

  const language = currentLanguage;

  return (
    <div className="contact_form">
      <form role="form" action="" method="post" id="contact_form">
        <div className="row">
          <RegistrationFormHeader activeTab={0} currentLanguage={language}/>
          <div className="hideOnBigScreens descBox">
            <div className="headerTitle">{language.businessInfoConfig}</div>
            <div className="titleDesc">{language.businessBoxDesc}</div>
          </div>
          <div className="col-lg-12">
            <h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12">
              {language.businessDesc}
            </h6>
            <div className="clearfix"></div>
            <div className="col-sm-6">
              <TextInput
                type="text"
                name="companyName"
                label={language.companyNameLabel}
                labelClass="control-label"
                placeholder={language.companyNameLabel}
                className="templateInput"
                id="company"
                onChange={onChange}
                value={user.companyName}
                errors={errors.companyName}
              />
            </div>
            <div className="col-sm-6">
              <TextInput
                type="text"
                name="btwNumber"
                label={language.vatNumberLabel}
                placeholder={language.vatNumberLabel}
                className="templateInput"
                id="btwNumber"
                onChange={onChange}
                value={user.btwNumber}
                errors={errors.btwNumber}
              />
            </div>

            <div className="col-sm-12" style={{marginBottom: 25}}>
              <TextInput
                type="text"
                name="address"
                label={language.addressLabel}
                placeholder={language.address1Placeholder}
                className="templateInput"
                id="address"
                onChange={onChange}
                value={user.address}
                errors={errors.address}
              />
            </div>

            <div className="col-sm-12" style={{marginBottom: 25}}>
              <TextInput
                type="text"
                name="address1"
                placeholder={language.address2Placeholder}
                className="templateInput"
                id="address"
                onChange={onChange}
                value={user.address1}
                errors=""
              />
            </div>

            <div className="col-sm-12">
              <TextInput
                type="text"
                name="address2"
                placeholder={language.address3Placeholder}
                className="templateInput"
                id="address"
                onChange={onChange}
                value={user.address2}
                errors=""
              />
            </div>

              <div className="col-sm-3">
              <SelectInput name="country"
                           label={language.selectCountryLabel}
                           onChange={onChange}
                           options={countries}
                           className="templateInput selectField"
                           defaultOption={language.selectCountry}
                           value={user.country}
                           errors={errors.country}
                           />
                </div>

            <div className="col-sm-3">

              <TextInput
                type="text"
                name="zipcode"
                label={language.zipcodeLabel}
                placeholder={language.zipcodeLabel}
                className="templateInput"
                id="zipcode"
                onChange={onChange}
                value={user.zipcode}
                errors={errors.zipcode}
              />
            </div>
            <div className="col-sm-6">
              <TextInput
                type="text"
                name="place"
                label={language.placeLabel}
                placeholder={language.placeLabel}
                className="templateInput"
                id="place"
                onChange={onChange}
                value={user.place}
                errors={errors.place}
              />
            </div>
          </div>
          <div className="clearfix"></div>
          <div className="col-lg-12" style={{marginLeft: 15, marginTop: 30}}>
            <Button onClick={onButtonClick.bind(this)}
                    name="stepOneNext"
                    value={language.btnNext}
                    icon="arrow-circle-right"
                    style={{margin: '0 auto 60px'}}/>
          </div>
        </div>
      </form>
    </div>
  );
};

export default RegistrationFormStepOne;

我尝试添加一些简单的验证,并且在我的主要组件中添加了验证功能,然后我检查按钮点击是否返回值是真还是假。如果它是真的,那么我将步骤状态设置为适当的值。如果我只验证第一步的表单字段,但当我尝试验证下一步的一个或多个表单字段时,它会起作用(现在我正在尝试验证第二步的第一个字段)

if(!user.firstName){
        formIsValid = false;
        errors.firstName = languageReg.firstnameEmpty;
    }

我比

警告:TextInput 正在将不受控制的文本类型输入更改为受控制。输入元素不应从不受控制切换到受控(反之亦然)。在组件的生命周期内决定使用受控或非受控输入元素。

没有验证功能,一切都完美无缺。

有什么建议吗?

编辑

    import React, {propTypes} from 'react';
import _ from 'lodash';

const TextInput = ({errors, style, name, labelClass, label, className, placeholder, id, value, onChange, type}) => {
  let wrapperClass = "form-group";

  if (errors) {
    wrapperClass += " " + "inputHasError";
  }

  return (
    <div className={wrapperClass} style={style}>
      <label htmlFor={name} className={labelClass}>{label}</label>
      <input type={type}
             className={className}
             placeholder={placeholder}
             name={name}
             id={id}
             value={value}
             style={{}}
             onChange={onChange}
      />
      <div className="errorBox">{errors}</div>
    </div>
  );
};

TextInput.propTypes = {
  name: React.PropTypes.string.isRequired,
  label: React.PropTypes.string,
  onChange: React.PropTypes.func.isRequired,
  type: React.PropTypes.string.isRequired,
  id: React.PropTypes.string,
  style: React.PropTypes.object,
  placeholder: React.PropTypes.string,
  className: React.PropTypes.string,
  labelClass: React.PropTypes.string,
  value: React.PropTypes.string,
  errors: React.PropTypes.string
};

export default TextInput;

这是第二步组件:

import React from 'react';
import Button from '../../common/formElements/button';
import RegistrationFormHeader from './registrationFormHeader';
import TextInput from '../../common/formElements/textInput';


const RegistrationFormStepTwo = ({user, onChange, onButtonClick, onButtonPreviousClick, errors, currentLanguage}) => {
    const language = currentLanguage;

    return (
        <div className="contact_form">
            <form role="form" action="" method="post" id="contact_form">
                <div className="row">
                    <RegistrationFormHeader activeTab={1} currentLanguage={language}/>
                    <div className="hideOnBigScreens descBox">
                        <div className="headerTitle">{language.personalInfoConfig}</div>
                        <div className="titleDesc">{language.personalBoxDesc}</div>
                    </div>
                    <div className="col-lg-12">
                        <h6 className="registrationFormDesc col-lg-10 col-lg-offset-1 col-lg-offset-right-2 col-xs-12">
                            {language.personalDesc}
                        </h6>
                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="text"
                                name="firstName"
                                label={language.firsnameLabel}
                                placeholder={language.firsnameLabel}
                                className="templateInput"
                                id="name"
                                onChange={onChange}
                                value={user.firstName}
                                errors={errors.firstName}
                            />
                        </div>
                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="text"
                                name="lastName"
                                label={language.lastnameLabel}
                                placeholder={language.lastnameLabel}
                                className="templateInput"
                                id="name"
                                onChange={onChange}
                                value={user.lastName}
                                errors={errors.lastName}
                            />
                        </div>

                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="text"
                                name="phone"
                                label={language.phoneLabel}
                                placeholder={language.phoneLabel}
                                className="templateInput"
                                id="phone"
                                onChange={onChange}
                                value={user.phone}
                                errors={errors.phone}

                            />
                        </div>

                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="text"
                                name="mobilePhone"
                                label={language.mobileLabel}
                                placeholder={language.mobileLabel}
                                className="templateInput"
                                id="phone"
                                style={{}}
                                onChange={onChange}
                                value={user.mobilePhone}
                                errors={errors.mobilePhone}
                            />
                        </div>
                        <div className="clearfix"></div>

                        <div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
                            <TextInput
                                type="text"
                                name="email"
                                id="email"
                                label={language.emailLabel}
                                placeholder={language.emailLabel}
                                className="templateInput"
                                style={{}}
                                onChange={onChange}
                                value={user.email}
                                errors={errors.email}
                            />
                        </div>

                        <div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
                            <TextInput
                                type="text"
                                name="userName"
                                label={language.usernameLabel}
                                placeholder={language.usernameLabel}
                                className="templateInput"
                                id="name"
                                onChange={onChange}
                                value={user.userName}
                                errors={errors.userName}
                            />
                        </div>

                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="password"
                                name="password"
                                label={language.passwordLabel}
                                placeholder={language.passwordLabel}
                                className="templateInput"
                                id="password"
                                onChange={onChange}
                                value={user.password}
                                errors={errors.password}
                            />
                        </div>
                        <div className="col-lg-6 col-md-6 col-sm-6 col-xs-12">
                            <TextInput
                                type="password"
                                name="confirmPassword"
                                label={language.passwordConfirmLabel}
                                placeholder={language.passwordConfirmLabel}
                                className="templateInput"
                                id="password"
                                onChange={onChange}
                                value={user.confirmPassword}
                                errors={errors.confirmPassword}
                            />
                        </div>

                    </div>
                    <div className="clearfix"></div>
                    <div className="col-lg-6 col-xs-6" style={{marginTop: 30}}>
                        <Button onClick={onButtonPreviousClick}
                                name="btnPrevious"
                                value={language.btnPrevious}
                                icon="arrow-circle-left"
                                style={{marginRight: 10, float: 'right'}}/>
                    </div>
                    <div className="col-lg-6 col-xs-6" style={{marginTop: 30}}>
                        <Button onClick={onButtonClick} name="stepTwoNext" value={language.btnNext}
                                icon="arrow-circle-right" style={{marginLeft: 10, float: 'left'}}/>
                    </div>
                </div>
            </form>
        </div>

    );
};

export default RegistrationFormStepTwo;

最佳答案

这就是警告存在的原因:当值被指定为未定义时,React 无法知道您是否打算渲染一个具有空值的组件,或者您是否打算让组件不受控制。它是错误的来源。

在将值传递给输入之前,您可以进行 null/undefined 检查。

a source

关于javascript - 类型文本不受控制的输入被控制警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38014397/

有关javascript - 类型文本不受控制的输入被控制警告的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 在院子里用@param 标签警告 - 2

    我试图使用yard记录一些Ruby代码,尽管我所做的正是所描述的here或here#@param[Integer]thenumberoftrials(>=0)#@param[Float]successprobabilityineachtrialdefinitialize(n,p)#initialize...end虽然我仍然得到这个奇怪的错误@paramtaghasunknownparametername:the@paramtaghasunknownparametername:success然后生成的html看起来很奇怪。我称yard为:$yarddoc-mmarkdown我做错了什么?

  3. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  4. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  5. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  6. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  7. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  8. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  9. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  10. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

随机推荐