gin how to check whether params was post or not - go

type listParams struct {
Status int `form:"status"`
Keyword string `form:"keyword"`
ShowType int `form:"show_type"`
}
func List(c *gin.Context) {
var ReqData listParams
_ = c.ShouldBind(&ReqData)
// I fetch this by PostForm() to check it empy if it equal to empty string
if stat := c.PostForm("status"); stat == "" {
ReqData.Status = -99
}
// .......
}
In this code, How can I know that was front-end post the status or not?
Because of the default value of go, if I check the reqData.Status == 0, it will always return true if the front-end didn't post it, but In my case, 0 is a meaningful value, So I can't check it by equal to 0.
So am I have the others way to check it?
PS: I tried and found out that gorm will not update the field in struct if I don't assign:
var d &User{} // User is a definition of user table
d.ID = 1
d.Name = "Joy"
// d.Status = 1 // It has this field, but I dont assign it
db.Model(&User{}).updates(&d)
Finally, status won't update to 0(In my understanding, d.Status should be 0)

Use a pointer type to circumvent the 0 default value:
type listParams struct {
Status &int `form:"status"`
Keyword string `form:"keyword"`
ShowType int `form:"show_type"`
}
The check if d.Status is nil, otherwise get the associated value

I think this constraint raises the need for having a sole public way to construct User.
type user struct { Status int Keyword string ShowTypeint}
func NewUser() (*user) { return &user{Status: -1} }
That way you ensure that user struct is only constructed through NewUser having Status default value Status always equal to -1.

Related

Why has methods are not generated using protoc 3.17.* if in protobuf repo they say it should?

Reading here: https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example the Golang example:
m := GetProto()
if (m.HasFoo()) {
// Clear the field:
m.Foo = nil
} else {
// Field is not present, so set it.
m.Foo = proto.Int32(1);
}
if I use:
protoc pkg/user.proto --go_out=. --go_opt=module=my_app --go-grpc_out=. --go-grpc_opt=module=my_app
with:
syntax = "proto3";
package example;
message MyPlayer {
uint64 id = 1;
optional string description = 2;
uint32 qty = 3;
optional uint64 age = 4;
}
it doesn't generate any has<T>() method.
Why?
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
Am I wrong if I use MyPlayer generated proto fields instead of methods?
Example:
if MyPlayer.description != nil {
description = *MyPlayer.description
}
instead of
description = MyPlayer.GetDescription()
which is not what I want (I want to detect nil values).
That docs is wrong, as reported here: https://github.com/golang/protobuf/issues/1336:
The documentation on https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example is incorrect. Using "optional" in proto3 makes the field be generated just as it would in proto2.
That doc is wrong. There are no Has methods in the generated code. Test for presence by comparing fields to nil.
Rewriting those examples correctly:
// Field foo does not have presence.
// If field foo is not 0, set it to 0.
// If field foo is 0, set it to 1.
m := GetProto()
if m.Foo != 0 {
// "Clear" the field:
m.Foo = 0
} else {
// Default value: field may not have been present.
m.Foo = 1
}
// Field foo has presence.
// If foo is set, clear it.
// If foo is not set, set it to 1.
m := GetProto()
if m.Foo != nil {
// Clear the field:
m.Foo = nil
} else {
// Field is not present, so set it.
m.Foo = proto.Int32(1)
}
PR to fix that doc:
protocolbuffers/protobuf#8788

How to set a bool value to drive<Bool>

var readIndicatorNeedsDisplay: Driver<Bool> = .empty()
public func bindcellEvents(readNotificationID: String) {
if let unreadNotificationIDs = UserDefaults.main?.unreadNotificationIDs, unreadNotificationIDs.contains(readNotificationID) {
readIndicatorNeedsDisplay = true
} else {
UserDefaults.main?.unreadNotificationIDs.append(readNotificationID)
readIndicatorNeedsDisplay = false
// Cannot assign value of type 'Bool' to type 'Driver<Bool>' (aka 'SharedSequence<DriverSharingStrategy, Bool>')
}
}
when i assign bool to driver Giving error: Cannot assign value of type 'Bool' to type 'Driver' (aka 'SharedSequence')
You're not supposed to assign values directly to a Driver, and attempting to do so shows your fundamental misunderstanding of RxSwift. You should probably step back, and learn the basics, then come back to this problem.
However, if you want to feed values to a stream, you could use a PublishRelay:
var readIndicatorNeedsDisplay = PublishRelay<Bool>()
public func bindcellEvents(readNotificationID: String) {
if let unreadNotificationIDs = UserDefaults.main?.unreadNotificationIDs, unreadNotificationIDs.contains(readNotificationID) {
readIndicatorNeedsDisplay.accept(true)
} else {
UserDefaults.main?.unreadNotificationIDs.append(readNotificationID)
readIndicatorNeedsDisplay.accept(false)
}
}

Appending value to struct of struct in Golang returns invalid memory address

I have a meal struct that "appends" another struct, except I want to add another struct "mealComponents".
type mealMain struct {
*model.Meal
Components []mealComponent `json:"components"`
}
type mealComponent struct {
*model.MealComponent
}
Where *model.Meal is as follows
type Meal struct {
ID int64 `json:"id"`
}
What I want is basically for "mealMain" struct to act like "Meal" struct, so that I can assign values and somehow append mealComponent as child (or maybe this is not a good idea? I'm open to suggestions)
However when I do something like this
var meal mealMain
meal.ID = 1
It throws runtime error: invalid memory address or nil pointer dereference at meal.ID assignment.
But if I do it like this:
type mealMain struct {
MealMain *model.Meal `json:"meal_main"`
Components []mealComponent `json:"components"`
}
Then assign it this way:
var meal mealMain
meal.mealMain.ID = 1
It works properly, but I have the return json even deeper like this:
{
"MealModel": {
"id": 1
}
}
What I want is this:
{
"id": 1
}
Note: I want to avoid changing the model.
If you don't want to change the model:
var meal = mealMain{
Meal: &Meal{},
}
meal.ID = 1
The point is that in the following struct *Meal is set to nil if you don't initialize it.
type mealMain struct {
*Meal
Components []mealComponent `json:"components"`
}
I'd probably create a function to never have to worry about the correct initialization ever again:
func newMealMain() mealMain {
return mealMain{
Meal: &Meal{},
}
}
Then your code would be:
var meal = newMealMain()
meal.ID = 1

Why is my struct method always returning false?

I'm trying to do validation on my form struct in a method that returns a bool, but I keep getting false even when it should be returning true..
If you look towards the end of the Validate method, you'll see I write validated := len(this.Errors) == 0 which should be making "validated" either true or false based on whether the Errors map has items or not, and then I return validated.
When I fill out my form accurately, there should be no errors yet I still get false when I should be getting true.
Can someone explain? Is this not how Go works?
form.go:
package models
import (
"../config"
"../util"
)
type Form struct {
Name string
Email string
Phone string
Message string
Thanks string
ErrorHandler
}
func (this *Form) Validate() bool {
this.Errors = make(map[string]string)
matched := util.MatchRegexp(".+#.+\\..+", this.Email)
if !util.IsEmpty(this.Email) {
if matched == false {
this.Errors["Email"] = config.EMAIL_INVALID
}
} else {
this.Errors["Email"] = config.EMAIL_EMPTY
}
if util.IsEmpty(this.Name) {
this.Errors["Name"] = config.NAME_EMPTY
}
if util.IsEmpty(this.Phone) {
this.Errors["Phone"] = config.PHONE_EMPTY
}
if util.IsEmpty(this.Message) {
this.Errors["Message"] = config.MESSAGE_EMPTY
}
validated := len(this.Errors) == 0
if validated {
this.Thanks = config.THANK_YOU
}
return validated
}
errorhandler.go:
package models
type ErrorHandler struct {
Errors map[string]string
}
func (this *ErrorHandler) HandleErr(err string) {
this.Errors = make(map[string]string)
this.Errors["Error"] = err
}
And this is where I try to call the Validate method -- in a function in my controller:
form := &models.Form{
Name: r.FormValue("name"),
Email: r.FormValue("email"),
Phone: r.FormValue("phone"),
Message: r.FormValue("message")}
if form.Validate() {
// This never runs because 'form.Validate()' is always false
}
I don't think the util.IsEmpty() is the culprit here.. just checks if the string is empty:
func IsEmpty(str string) bool {
return strings.TrimSpace(str) == ""
}
Any help would be appreciated!
It's best to debug this kind of problem with a log statement like:
log.Printf("form: %v", form)
before calling validate, so it's clear what the input data looks like.
Greetings, Philip

When would you use an enum with associated values in preference to a static factory?

In Swift you can define an enum and give it a property via an associated value, e.g.:
protocol SizeEnum {
var length : Double? { get } // Length should be >= 0 - has to be an Optional for errors
}
enum SizesEnum : SizeEnum {
case Short(length : Double) // 0 <= length <= maxShort
case Long(length : Double) // length > maxShort
private static let maxShort = 1.0
var length : Double? {
get {
switch self {
case let .Short(length):
if length >= 0 && length <= SizesEnum.maxShort { // Need to error check every access
return length
}
case let .Long(length):
if length > SizesEnum.maxShort { // Need to error check every access
return length
}
}
return nil // There was an error
}
}
}
SizesEnum.Short(length: 0.5).length // [Some 0.5]
SizesEnum.Short(length: 2).length // nil
SizesEnum.Long(length: 2).length // [Some 2.0]
SizesEnum.Long(length: -1).length // nil
However this is not ideal because:
The error checking for the length parameter can only be done on access, you cannot intercept the init
The length parameter is surprisingly long winded
An alternative, which seems better to me, is to use a static factory, e.g.:
protocol SizeStruct {
var length : Double { get } // Length should be >= 0 - is *not* an Optional
}
struct SizesStruct : SizeStruct {
static func Short(length : Double) -> SizeStruct? {
if length >= 0 && length <= maxShort { // Check at creation only
return SizesStruct(length)
}
return nil
}
static func Long(length : Double) -> SizeStruct? {
if length > maxShort { // Check at creation only
return SizesStruct(length)
}
return nil
}
let length : Double
private static let maxShort = 1.0
private init(_ length : Double) {
self.length = length
}
}
SizesStruct.Short(0.5)?.length // [Some 0.5]
SizesStruct.Short(2)?.length // nil
SizesStruct.Long(2)?.length // [Some 2.0]
SizesStruct.Long(-1)?.length // nil
Given that the static factory solution is neater, when would I actually use an enum with values? Am I missing something? Is there a killer use case?
In response to drewag
For Optional other languages, e.g. Java and Scala, you use factories, the Java version is described here: http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html the factory is the of method.
In Swift you would do something like:
class Opt { // Note only Some stores the value, not None
//class let None = Opt() - class variables not supported in beta 4!
class Some<T> : Opt {
let value : T
init(_ value : T) {
self.value = value
}
}
private init() {} // Stop any other ways of making an Opt
}
Opt.Some(1).value // 1
This is probably the optimal example for enum since no error checking is required, but even so the factory version is competitive. The Optional example is so straightforward you don't even need a factory, you just create the Somes directly. Note how None doesn't use any storage.
The Barcode example shows how much better the factory technique is; in practice not all collections of 4 Ints are a valid UPCA and not all Strings are a valid QR Code, therefore you need error checking which is painful with enums. Here is the factory version:
class Barcode { // Note seperate storage for each case
class UPCABarcode : Barcode {
let type : Int, l : Int, r : Int, check : Int
private init(type : Int, l : Int, r : Int, check : Int) {
(self.type, self.l, self.r, self.check) = (type, l, r, check)
}
}
class func UPCA(#type : Int, l : Int, r : Int, check : Int) -> UPCABarcode? {
if ok(type: type, l: l, r: r, check: check) {
return UPCABarcode(type: type, l: l, r: r, check: check)
}
return nil
}
class func QRCode(#s : String) -> Barcode? { // Have not expanded this case; use same pattern as UPCA
return Barcode()
}
private init() {} // Prevent any other types of Barcode
class func ok(#type : Int, l : Int, r : Int, check : Int) -> Bool {
return true // In practice has to check supported type, range of L and R, and if check digit is correct
}
}
Barcode.UPCA(type: 0, l: 1, r: 2, check: 3)
If you use the enum version of Barcode then every time you use a Barcode you have to check its validity because there is nothing to stop invalid barcodes. Whereas the factory version does the checking at creation. Note how Barcode has no storage and UPCA has custom storage. I didn't code QRCode because it uses the same design pattern as UPCA.
My impression is that the enum version looks great in tutorials but soon becomes painful in practice because of error handling.
I believe the biggest killer use case is Optional. It is built into the language, but an optional is simply an enum:
enum Optional<T> {
case None
case Some(T)
}
In this case, a member variable like value would not make sense because in the None case, there is literally no value.
Also, right out of the Swift tour:
enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
With a struct, there would be a lot of wasted member variables and a confusing interface to model this kind of data.
I don't believe it makes sense to use an associated value for an enum if the same type is used for every case. In that case a member variable is cleaner. The focus of associated values is to more accurately model certain types of data. The most useful cases are ones where different instances of a type can have different data associated with them. This could potentially be done with subclasses but then one would need to downcast to access more specific variables and the declarations would be much more verbose. Enums are a concise way to represent this type of data.
Another example could be web requests:
struct NetRequest {
enum Method {
case GET
case POST(String)
}
var URL: String
var method: Method
}
var getRequest = NetRequest(URL: "http://drewag.me", method: .GET)
var postRequest = NetRequest(URL: "http://drewag.me", method: .POST("{\"username\": \"drewag\"}"))
When I think of "enum" I don't think of "factory" at all. Normally factories are for larger more complex class structures. Enums are supposed to be very small pieces of data with little logic.

Resources