草庐IT

swift - 为什么在我的结构中调用 self.init 之前出现错误 'self'?

coder 2023-09-09 原文

我构建了这个结构来处理我计划在某些自定义类中使用的特定类型的数据。
我的问题是 featureSubSet 变量能够成为几个枚举之一,当这个结构被初始化时它不知道它将是哪个枚举,所以我将它声明为 Any。

当调用 public init 时,它会将数据适本地汇集到所需的私有(private) init 方法,以便它可以正确和完整地初始化。

我在公共(public) init 方法结束时收到错误,但我不确定如何让它消失。

struct Feature {
//MARK: Variables needed for Feature
var featureSet: FeatureType
var featureSubSet: Any
var effect: String
var active: Bool?
var skill: Skill?
var ability: Ability?

public init(base: String, sub: String, effect: String, skill: Skill? = nil, ability: Ability? = nil) {
    switch base {
    case featureCategoryList()[0]: // Character Features
        self.init(CharacterFeature: sub, effect: effect)
    case featureCategoryList()[1]: // Combat Features
        self.init(CombatFeature: sub, effect: effect)
    case featureCategoryList()[2]: //Skill Features
        guard let newSkill = skill else {
            print("No skill")
            return
        }
        self.init(SkillFeature: sub, effect: effect, skill: newSkill)

    default:
        print("Somehow you picked something not on the list.")
        break
    }
}

private init(CharacterFeature sub: String, effect: String) {
    self.featureSet = .CharacterFeatures
    self.featureSubSet = CharacterFeatures.init(rawValue: sub)!
    self.effect = effect
}

private init(CombatFeature sub: String, effect: String) {
    self.featureSet = .CombatFeatures
    self.featureSubSet = CharacterFeatures.init(rawValue: sub)!
    self.effect = effect
}

private init(SkillFeature sub: String, effect: String, skill: Skill) {
    self.featureSet = .SkillFeatures
    self.featureSubSet = CharacterFeatures.init(rawValue: sub)!
    self.skill = skill
    self.effect = effect
}

//MARK: Feature functions
func string() -> String {
    //TODO: Make a string output for what the feature is.
    return ""
}
}

最佳答案

这是一种不正确的方法。如果您发现自己将某些内容存储为 Any,那么几乎可以肯定您走错了路。探索这段代码很困难,因为它定义了很多其他类型,但看看它,不清楚为什么你在这里需要 AnyfeatureSubSet 始终是 CharacterFeatures 类型。枚举的所有值都是相同的“类型”。

你这里有错误:

    case featureCategoryList()[2]: //Skill Features
        guard let newSkill = skill else {
            print("No skill")
            return
        }

在这里:

    default:
        print("Somehow you picked something not on the list.")
        break
    }

这会在没有初始化 self 的情况下返回(这可能是您的问题)。如果你可以失败,那么你需要使它成为一个可选的初始化器(init?)或一个抛出的初始化器,或者你需要调用 fatalError() 或类似的崩溃方法错误。你不能不初始化就直接返回。

不过,我强烈建议您重新设计它。我看不出参数应该是字符串的任何理由。与其传入 "character" 并在某个表中查找,不如让调用者将 .character.combat 作为枚举传递(你已经有了枚举)。

请注意,在 Swift 3 中,枚举大小写应始终以小写字母开头。

有点难以理解您的代码中发生了什么,但它看起来根本不应该是一个结构体。它看起来像一个枚举。像这样:

enum CharacterFeature {
    // Features for characters
}

enum CombatFeature {
    // Features for combat
}

enum Skill {
    // skills
}

enum Effect {
    // effects
}

enum Feature {
    case character(CharacterFeature, Effect)
    case combat(CombatFeature, Effect)
    case skill(Skill, Effect)
}

或者,您可以在此处使用结构,尤其是当所有功能共享更多内容时:

struct Feature {
    enum Kind {
        case character(CharacterFeature, Effect)
        case combat(CombatFeature, Effect)
        case skill(Skill, Effect)
    }

    let kind: Kind
    let effect: Effect
}

关键是您通常应该使用显式类型,而不是字符串。如果您发现自己需要太多可选值,那么您通常做错了什么。

关于swift - 为什么在我的结构中调用 self.init 之前出现错误 'self'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44180710/

有关swift - 为什么在我的结构中调用 self.init 之前出现错误 'self'?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  6. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  7. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐