我正在尝试做这样的事情:
使用名为 env 的标签定义结构:
type Env struct {
Port string `env:"PORT"`
}
使用 os.Getenv 调用一些函数来获取环境变量名称,并将其设置到结构中。
现在,我有这个:
package main
import (
"fmt"
"os"
"reflect"
)
func ParseEnv(t interface{}, v interface{}) {
it := reflect.TypeOf(t)
for i := 0; i < it.NumField(); i++ {
field := it.Field(i)
value := os.Getenv(field.Tag.Get("env"))
if value == "" {
continue
}
reflect.ValueOf(v).Elem().FieldByName(field.Name).SetString(value)
}
}
type Env struct {
Port string `env:"PORT"`
DatabaseURL string `env:"DATABASE_URL"`
}
func main() {
os.Setenv("PORT", "8080")
os.Setenv("DATABASE_URL", "postgres://user:pass@host:5432/my-db")
env := Env{}
ParseEnv(env, &env)
fmt.Println(env)
}
http://play.golang.org/p/b8uPPVo4aV
但是,如您所见,我必须将引用和指针都传递给我的函数。
虽然这有效,但它非常丑陋(至少我认为是这样)。
如果我尝试只传递指针,我无法得到正确的类型(因为它将是一个*interface{}),而且,如果我只传递引用,我不能' t 使用 reflect 设置值(即使我可以,它也不起作用)。
有没有一种明智的方法可以做到这一点?
最佳答案
下面是做你想做的事情的“更理智”的方式。您会注意到,我们不需要传入该结构的两个副本,而只需要一个指向该结构的指针。
func ParseEnv(val interface{}) {
ptrRef := reflect.ValueOf(val)
if ptrRef.Kind() != reflect.Ptr {
panic("pointer to struct expected")
}
ref := ptrRef.Elem()
if ref.Kind() != reflect.Struct {
panic("pointer to struct expected")
}
refType := ref.Type()
for i := 0; i < refType.NumField(); i++ {
field := refType.Field(i)
value := os.Getenv(field.Tag.Get("env"))
if value == "" {
continue
}
ref.Field(i).SetString(value)
}
}
上面的函数应该按以下方式调用:
ParseEnv(&env)
关于pointers - 反射(reflect) : setting a field of a pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31690160/
在我的Rails应用程序中,我收到来自brakeman的以下安全警告。使用模型属性调用的不安全反射方法常量化。这是我的代码正在执行的操作。chart_type=Chart.where(id:chart_id,).pluck(:type).firstbeginChartPresenter.new(chart_type.camelize.constantize.find(chart_id))rescueraise"Unabletofindthechartpresenter"end根据我的研究,我还没有找到任何具体的解决方案。我听说你可以创建一个白名单,但我不确定brakeman在寻找什么。
我很好奇这是如何工作的。例如,如果我创建一个基于工厂模式的类,您可以在其中“注册”类供以后使用,然后执行类似FactoryClass.register('YourClassName',[param,param,...]);FactoryClass.create('your_class_name').call_method_from_this_object其中'class_name'是映射到值的散列中的键:ClassName有没有类似phpreflection的东西,我可以在哪里创建基于字符串名称的类的实例并传入参数?(在php中,参数将是它们的数组,php然后知道如何处理)所以如果我们
我是从PHP开始接触ruby的。我怎么能用ruby做下一件事?$className='ArrayObject';$arrayObject=new$className(); 最佳答案 你可以这样做:arrayObject=Object::const_get('Array').new 关于ruby-Ruby中的反射。通过给定的类名实例化一个对象,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/qu
我想在Ruby中做一些相当繁重的反射。我想创建一个函数,该函数返回调用堆栈更高层的各种调用函数的参数名称(只要高一点就足够了,但为什么要停在那里?)。我可以使用Kernel.caller,转到文件并解析参数列表,但这会很丑陋且不可靠。我想要的功能将按以下方式工作:moduleAdefmethod1(tuti,fruity)fooenddefmethod2(bim,bam,boom)fooenddeffooprintcaller_args[1].join(",")#the"1"meanonestepupthecallstackendendA.method1#prints"tuti,fru
我是Rails的新手(通常是Python专家),只是为了好玩而尝试构建一个简单的任务管理器应用程序。我正在使用Devise进行身份验证,并且有一个我试图与用户关联的任务对象。我已将以下内容添加到任务模型中:classTask并且我在我的Devise用户模型中添加了以下内容:classUser>end每当我添加此信息时,我都会运行:rakedb:migrate。然后它给了我一个错误,当我试图用它做任何事情时,user_id的数据库字段不存在。我确信这是我所缺少的相当简单的东西。感谢您的帮助。 最佳答案 向模型添加belongs_to(
我试图让Matz和Flanagan的“Ruby编程语言”元编程章节进入我的脑海,但是我无法理解我梦寐以求的以下代码片段的输出:pModule.constants.length#=>88$snapshot1=Module.constantsclassANAME=:abc$snapshot2=Module.constantsp$snapshot2.length#=>90p$snapshot2-$snapshot1#=>["A","NAME"]endpModule.constants.length#=>89pModule.constants-$snapshot1#=>["A"]pA.cons
对于普通列,您可以通过columns类方法获取它们。但是,如果在关系方法中设置了foreign_key选项,关联的名称可能会完全不同。例如,给定classPosthas_many:comments,:foreign_key=>:message_id#thisisacontrivedexampleend如果我做了Post.column_names,我可以得到message_id,但是有什么方法可以得到comments吗? 最佳答案 Model.reflections提供有关模型关联的信息。它是一个以关联名称为关键字的Hash。例如Po
之前它运行良好。我一直在玩一点配置。所以可能是我在不知不觉中更改了一些配置。这里是environment/development.rb的配置config.cache_classes=false#Logerrormessageswhenyouaccidentallycallmethodsonnil.config.whiny_nils=true#Showfullerrorreportsanddisablecachingconfig.consider_all_requests_local=trueconfig.action_view.debug_rjs=trueconfig.action_c
我有这样的HTMLone当我使用document.getElementById('foo').innerHTML=document.getElementById('foo').innerHTML.replace("one","two");innerHTML被替换,但它没有反射(reflect)在浏览器中。如果我提醒innerHTML,我可以看到它现在已被更改,但在浏览器中它仍然显示旧选项。有没有办法让浏览器识别这个更改?提前致谢。 最佳答案 我在Firefox3.5中工作正常WorkingDemo编辑:您必须使用IE。您需要创建一个
我有一些Angular变量设置如下:$scope.pane=[];$scope.pane.count=0;$scope.pane.max=5;然后我像这样在HTML中显示变量:{{pane.count}}这工作正常并按预期显示0。现在,如果我在任何时候更新变量,更新都会发生(我可以使用console.log看到)但HTML中的打印版本不会更新。例如setTimeout(function(){$scope.pane.count=1;},1000);我正在使用Angularv1.3。我做错了什么? 最佳答案 为了让angular知道变化