【问题标题】:Making constant global variables of a custom struct type制作自定义结构类型的常量全局变量
【发布时间】:2016-11-27 07:26:47
【问题描述】:

我想创建一个“类”来处理输入验证。我首先创建了一个Input 类型,它是一个用于存储用户输入的字符串,以及一个REGP 类型,它存储正则表达式模式和模式描述。我创建了两个常量实例REGP_LOGINNAMEREGP_PASSWORD。但我收到const initializer REGP literal is not a constant 的错误。为什么?

package aut

import "regexp"

type Input string

type REGP struct {
    pattern string
    Descr   string
}

const REGP_LOGINNAME = REGP{ //const initializer REGP literal is not a constant
    "regex pattern 1",
    "regex description 1",
}

const REGP_PASSWORD = REGP{ //const initializer REGP literal is not a constant
    "regex pattern 2",
    "regex description 2",
}

func (i Input) isMatch(regp REGP) bool {
    isMatchREGP, _ := regexp.MatchString(regp.pattern, string(i))
    return isMatchREGP
}

错误信息:

/usr/local/go/bin/go build -i [/home/casper/gopath/codespace_v2.6.6/dev/server_side/golang/go_codespace_v2.1/server/lib/aut]
# _/home/casper/gopath/codespace_v2.6.6/dev/server_side/golang/go_codespace_v2.1/server/lib/aut
./validation.go:15: const initializer REGP literal is not a constant
./validation.go:20: const initializer REGP literal is not a constant
Error: process exited with code 2.

【问题讨论】:

  • 有布尔常量、符文常量、整数常量、浮点常量、复数常量和字符串常量。 REGP 不是其中之一。
  • @JimB - 你的意思是我不能将自定义类型设为常量?你有什么想法让它看起来更好吗?
  • 正确golang.org/ref/spec#Constants。大多数代码会使用一个变量,或者只是将正则表达式字符串设为 const
  • 有没有办法将patternDescr包装在一起形成全局变量?
  • 是的,您可以创建一个 REGP 类型的全局变量。

标签: go types constants


【解决方案1】:

我终于发现似乎不可能使REGP 指针或其内部变量保持不变。所以我只是将它们设为全局变量。

package aut

import "regexp"

type Input string

type REGP struct {
    pattern string
    Descr   string
}

var REGP_LOGINNAME = REGP{
    pattern: "/^(?=^.{6,20}$)^[a-zA-Z][a-zA-Z0-9]*[._-]?[a-zA-Z0-9]+$/",
    Descr:   "regex description 1",
}

var REGP_PASSWORD = REGP{
    pattern: "/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[0-9a-zA-Z!@#$%^&*()]*$/",
    Descr:   "regex description 2",
}

func (i Input) isMatch(regp REGP) bool {
    isMatchREGP, _ := regexp.MatchString(regp.pattern, string(i))
    return isMatchREGP
}

【讨论】:

    【解决方案2】:

    Go 中的常量只能是标量值(例如 2true3.14"and more")或仅由常量组成的任何表达式(例如 1 + 2"hello " + "world"、或2 * math.Pi * 1i)。

    这意味着不能将非标量值的结构类型(例如 REGP_LOGINNAME)分配给常量。相反,使用变量:

    var (
        REGP_LOGINNAME = REGP{
            pattern: `/^(?=^.{6,20}$)^[a-zA-Z][a-zA-Z0-9]*[._-]?[a-zA-Z0-9]+$/`,
            Descr:   "regex description 1",
        }
        REGP_PASSWORD = REGP{
            pattern: `/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[0-9a-zA-Z!@#$%^&*()]*$/`,
            Descr:   "regex description 2",
        }
    )
    

    进一步阅读

    旁白:当然,我不知道你的用例,但我真的真的怀疑你真的需要或想要使用正则表达式来验证用户密码.相反,请考虑通过OpaqueString profile of PRECIS(用于处理和强制执行 unicode 字符串安全的框架;不透明字符串配置文件旨在处理密码)传递它。同样,UsernameCaseMapped 和 UsernameCasePreserved 配置文件(也在链接包中实现)可用于用户名,以确保您最终不会得到两个看起来相同但具有不同 unicode 字符的用户名。当然,也可以进行进一步的验证。

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 2012-01-21
      相关资源
      最近更新 更多